• OpenCV学习(26) 直方图(3)


          本章中我们学习一下通过backproject直方图,得到一副图像中每个像素属于该直方图的概率。在下边原始图中(左图),我们框选了一块四边形的区域,计算该区域的灰度直方图,然后通过下面的函数calcBackProject,计算图像src中每个像素在直方图中的概率,最终的结果在result中,result中每个像素表示该像素在直方图中的概率,我们对得到的结果进行二值化,就得到下边右图的结果。

          我们框选了一块白云区域,但从背投影结果中,海浪的边缘在直方图中的概率也很高,这是因为它们的灰度比较相似,如果我们只想白云的位置,最好使用三通道的直方图,然后背投影。


    cv::calcBackProject(&src,
        1,            // 一副图像
        channels,     // 使用的channel
        hist,    // backprojecting的直方图
        result,       // 结果图像
        ranges,       //像素值范围
        255.0         //缩放因子
        );

    imageimage

    完整的代码:

    int main( int argc, char** argv )
    {
    Mat src, dst;

    /// 以单通道方式打开图像
    src = cv::imread("../waves.jpg", 0);

    if( !src.data )
    { return -1; }

    //选择一个ROI区域
    cv::Mat imageROI;

    imageROI = src(cv::Rect(360,55,40,50));

    int histSize[1]; //bins的数目,对灰度图像通常是256
    float hranges[2];//最大和最小的像素值
    const float* ranges[1];//指向hranges
    int channels[1]; //在本程序中,只用了一个channel
    bool uniform = true; bool accumulate = false;
    histSize[0]= 256;
    hranges[0]= 0.0; //最小像素值
    hranges[1]= 255.0; //最大像素值
    ranges[0]= hranges;
    channels[0]= 0; // 缺省状态下,我们取channel0
    //结果直方图
    Mat hist;
    Mat result;
    /// 计算直方图
    //第二个参数1表示只对一副图像进行直方图处理
    //第三个参数表示只处理channel 0,对多个channel的图像,可以选1,2等等。
    //第四个参数Mat(),表示不使用掩码
    //hist是直方图结果
    //第六个参数1表示是1维直方图
    //第七个参数,直方图bin的数目
    //第八个参数是像素取值范围,第九个参数是各维取值范围相同,第十个参数是是否累加,如果处理多个图像,需要这个参数。
    calcHist( &imageROI, 1, 0, Mat(), hist, 1, histSize, ranges, uniform, accumulate );

    //直方图结果归一化
    cv::normalize(hist,hist,1.0);

    //计算back
    cv::calcBackProject(&src,
    1, // 一副图像
    channels, // 使用的channel
    hist, // backprojecting的直方图
    result, // 结果图像
    ranges, //像素值范围
    255.0 //缩放因子
    );

    // 二值化图像,看是否能分开前景和背景
    cv::threshold(result,result,20,255,cv::THRESH_BINARY);
    /// 显示直方图
    namedWindow("result", CV_WINDOW_AUTOSIZE );
    imshow("result", result );

    // 显示原图像
    cv::rectangle(src, cv::Rect(360,55,40,50), cv::Scalar(0,0,255));

    namedWindow("image", CV_WINDOW_AUTOSIZE );
    imshow("image", src);

    while(1)
    waitKey(0);

    return 0;

    }

    程序代码:工程FirstOpenCV20

          下面的程序中,使用BGR三通道直方图,注意我们框选的范围包括蓝天,也包括白云,之所以包括蓝天白云,是因为这样可以剔除海水边缘白色,我们还对原始图像进行了减色处理。

    imageimage

    程序代码:工程FirstOpenCV21

     

  • 相关阅读:
    Tx.Origin 用作身份验证
    区块链夺宝合约
    (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
    Oracle查看用户密码过期,修改永不过期
    springboot测试
    (转)Springboot定时任务
    书单
    (转)redis分布式锁-SETNX实现
    mybatis-generator 代码自动生成工具
    (转)通过Ajax使用FormData对象无刷新上传文件
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/3415877.html
Copyright © 2020-2023  润新知