ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

遥感图像处理-阴影检测

2019-07-13 12:05:06  阅读:282  来源: 互联网

标签:src int double cols 阴影 ++ 遥感 图像处理 M3


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

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

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

         下面我们来看一下效果

 

 

 

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

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

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

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

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

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

#include <iostream>
#include <opencv2/opencv.hpp>
#include <math.h>
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<Vec3b>(y, x)[0] + (double)src.at<Vec3b>(y, x)[1] + (double)src.at<Vec3b>(y, x)[2]) < 250) {//限制亮度
                var[i] = sqrt(varOf3((double)src.at<Vec3b>(y, x)[0], (double)src.at<Vec3b>(y, x)[1], (double)src.at<Vec3b>(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<uchar>(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<uchar>(y, x) == 255) {
                M3.at<Vec3b>(y, x)[0] = 255;
                M3.at<Vec3b>(y, x)[1] = 0;
                M3.at<Vec3b>(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;
}

 

标签:src,int,double,cols,阴影,++,遥感,图像处理,M3
来源: https://blog.csdn.net/jacke121/article/details/95735655

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有