遥感图像处理-阴影检测

原文:https://blog.csdn.net/WHU_StudentZhong/article/details/90719928

     这次的任务是遥感图像的阴影提取,看上去好像有一点高大上的样子,让人有些摸不到头脑。我先到网上查找了一下,主要的方法都是用二值化,配合Canny算子或者Sobel算子之类的来提取阴影的面积,但是我觉得这样做比较复杂,而且效果也不一定很好。于是我就变了一个思路,来用阴影本身的特点来进行提取。

     首先要说明的是,我要处理的图像都是光照条件比较好的,所以阴影部分的亮度就会比其他区域的亮度明显低不少;另外,由于亮度的降低,导致其色调比较浅,所以R、G、B三个通道数值的方差肯定比较小。为了编写代码,我先做了一些尝试,最后确定了效果比较好的阈值,最后计算了阴影面积的比重,并显示在窗口的标题上。

         下面我们来看一下效果

 

 

遥感图像处理-阴影检测_第1张图片

 

遥感图像处理-阴影检测_第2张图片

阴影有点多,树都遮挡了。

从图中可以看到,最终的效果还是非常好的,目测估计准确率在90%以上(哈哈哈)

下面是其他图片的处理效果

无论是遥感影像还是生活照的效果都不错哦。

下面就是代码部分了。(提醒:环境是VS2017+OPENCV4.1)

大家有什么好的办法,记得和我讨论分享一下哦。(^_^)

#include 
#include 
#include 
using namespace std;
using namespace cv;
 
double varOf3(double x1, double x2, double x3) {
    double mean = (x1 + x2 + x3) / 3;
    return (pow((x1 - mean), 2) + pow((x2 - mean), 2) + pow((x3 - mean), 2));
}
Mat ShadowExtraction(Mat src,int type=1);
 
int main()
{
    //读取图片
    char filename[] = "Color4.bmp";
    Mat src = imread(filename);
    resize(src, src, Size(720, (720 * src.rows / src.cols)));//将图像的尺寸缩放到适合屏幕观看
    imshow("Previous", src);
    ShadowExtraction(src);
    return 0;
}
 
Mat ShadowExtraction(Mat src, int type ) {
    int rows = src.rows, cols = src.cols;
    Mat M(rows, cols, CV_8UC1);
    double* var = new double[rows*cols];
    int i = 0;
    for (int x = 0; x < cols; x++) {
        for (int y = 0; y < rows; y++) {
            if (((double)src.at(y, x)[0] + (double)src.at(y, x)[1] + (double)src.at(y, x)[2]) < 250) {//限制亮度
                var[i] = sqrt(varOf3((double)src.at(y, x)[0], (double)src.at(y, x)[1], (double)src.at(y, x)[2]));
            }
            else {
                var[i] = 255;
            }
            i++;
        }
    }
    int j = 0;
    for (int x = 0; x < cols; x++) {
        for (int y = 0; y < rows; y++) {
            M.at(y, x) = (uchar)(var[j]);//把方差作为亮度进行赋值
            j++;
        }
    }
    //imshow("Before Binarization", M);
    switch (type) {
    case 1://轻度阴影提取
        equalizeHist(M, M);//可以过滤掉颜色比较浅的部分
        break;
    case 2://强力阴影提取
        break;
    }
    /*int block_size = 25;
    int const_value = 10;
    adaptiveThreshold(M, M, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV, block_size, const_value);*/
    threshold(M, M, 70, 255, THRESH_BINARY_INV);//把图像二值化
    medianBlur(M, M, 7);//中值滤波,去除小斑点
    imshow("Shadow", M);
    Mat M3 = src.clone();//M3是最后阴影提取后的结果
    double count = 0.0;
    for (int x = 0; x < cols; x++) {//给识别出来的阴影上色
        for (int y = 0; y < rows; y++) {
            if (M.at(y, x) == 255) {
                M3.at(y, x)[0] = 255;
                M3.at(y, x)[1] = 0;
                M3.at(y, x)[2] = 0;
                count++;
            }
        }
    }
    char str1[64] = "Shadow in Previous";
    char str2[64];
    sprintf_s(str2, "  ||  Weight of Shadow:%.2lf%%", 100.0*count / rows / cols);//阴影量
    strcat_s(str1, str2);
    //erode(M3, M3, Mat());//腐蚀
    //dilate(M3, M3, Mat());//膨胀
    imshow(str1, M3);//显示最后处理结果的
 
 
    waitKey(0);
 
    delete[] var;
    return M3;
}

 

你可能感兴趣的:(视觉相关)