阴影检测(shadow detect)

不管是无人机影像或者其它方式摄取的图像,由于光照,难免会存在阴影,笔者这篇文章介绍检测阴影一种简单的方式。

参考论文:

1、Damaged Building Detection in Aerial Images using Shadow Information

2、Linearized Vegetation Indices Based on aFormal Statistical Framework

主要原理:(以NDVI算法举一反三,ndvi(归一化植被指数)

NDVI=nir-red/(nir+red)

第一步:读入图像,通道分离,并对各通道中值滤波,滤波核大小可以不一样,自行调试。

第一步:计算如下值,注意的时,计算的时候一定要数据类型转换,将bguint8 格式转为double 或者float ,否则计算的结果有问题!!!!!!

第二步:构造mask, 上式大于某一阈值的为1,反之为0,笔者这幅Image 用的0.2

第三步:本来用matlabbwareopen 这个函数,这个函数是移除指定面积大小小于某一个阈值的像素,因为在opencv中没有这个函数,要不然自己写,要不然继续去挖掘python 其它图像处理包,本人是懒人,所以在skimage 找的函数:

remove_small_objects。自己写的话,步骤如下:

1、二值化图像,找轮廓

2、筛选轮廓,轮廓面积小于某个阈值的,保存

3、将满足2的轮廓中像素值全部赋值0

第四步:膨胀运算,掩模膨胀 - 掩模 = 阴影轮廓。
阴影检测(shadow detect)_第1张图片
阴影检测(shadow detect)_第2张图片
阴影检测(shadow detect)_第3张图片
code:


# -*- coding: utf-8 -*-
import numpy as np
import cv2
from skimage.morphology import remove_small_objects
im1=cv2.imread(r'C:\Users\Y\Desktop\im1.jpg')
b,g,r=np.double(cv2.split(im1))
shadow_ratio = (4/np.pi)*np.arctan2((b-g),(b+g)) #mutiply 4/pi is to ensure value[0,1]
shadow_mask=shadow_ratio>0.2
#cv2.imshow("shadow_mask",np.uint8(shadow_mask*255))
shadow_mask[:5,:]=0
shadow_mask[-5:,:]=0
shadow_mask[:,:5]=0
shadow_mask[:,-5:]=0#边界上的值=0
#cv2.imshow("shadow_mask1",np.uint8(shadow_mask*255))
shadow_mask=remove_small_objects(shadow_mask, min_size=100, connectivity=3)
# opencv 中没有matlab 中类似bwareaopen的函数,二值图像面积开运算
cv2.imshow("shadow_mask1",np.uint8(shadow_mask*255))
kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
kernel[1,0]=0
kernel[3,0]=0
kernel[1,4]=0
kernel[3,4]=0
shadow_mask1=np.uint8(shadow_mask*1)
mask=cv2.dilate(shadow_mask1,kernel)-shadow_mask1
#cv2.imshow("boundary",np.uint8(mask*255))
#substarct shadow_mask is to get boundary
#get boundary
[row,col]=np.where(mask==1)
#for i in range(len(row)-1):
#    cv2.line(im1,(col[i],row[i]),(col[i+1],row[i+1]),(0,0,255),1)
im1[row,col,:]=im1[40,40,:]
cv2.imshow("original-shadow",im1)
cv2.waitKey(0)

你可能感兴趣的:(图像处理,python)