OpenCV直方图操作综合

原图:

直方图均值

equalizeHist(gray_src,dst);

效果:

直方图计算,显示

#include <iostream>
#include <opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
    const int histszie=256;
    float range[]={0,255};
    const float *ransize={range};
    Mat dst;
    Mat src=imread("E:/opencv/cv_1/luff.jpg");
    Mat gray_src;
    cvtColor(src,gray_src,CV_BGR2GRAY);

    equalizeHist(gray_src,dst);

    imshow("dst",dst);
    //imwrite("hist.jpg",dst);

    vector<Mat>gray_planes;
    Mat my_hist,oth_hist;

    Mat hist_image(512,400,CV_8UC3,Scalar(0,0,0));//初始化对象
    //计算直方图
    //传入的单通道图像,不需要split
    calcHist(&gray_src,1,0,Mat(),my_hist,1,&histszie,&ransize,true,false);
    calcHist(&dst,1,0,Mat(),oth_hist,1,&histszie,&ransize,true,false);
    int hist_h=400;
    //归一化
    normalize(my_hist,my_hist,0,hist_h,NORM_MINMAX,-1,Mat());
    normalize(oth_hist,oth_hist,0,hist_h,NORM_MINMAX,-1,Mat());
    for(int i=1;i<histszie;i++)
    {
        //绿色my_hist表示原图直接转为灰度后的直方图
        line(hist_image,Point((i-1)*2,hist_h-cvRound(my_hist.at<float>(i-1))),
             Point((i)*2,hist_h-cvRound(my_hist.at<float>(i))),Scalar(0,255,0),1,LINE_AA);
        //红色oth_hist表示原图灰度后,直方图均值后的直方图效果
        line(hist_image,Point((i-1)*2,hist_h-cvRound(oth_hist.at<float>(i-1))),
             Point((i)*2,hist_h-cvRound(oth_hist.at<float>(i))),Scalar(0,0,255),1,LINE_AA);
    }

    imwrite("hist_image.jpg",hist_image);
    imshow("Hist",hist_image);
    imshow("gray",gray_src);
    //imshow("dst",dst);
    waitKey(0);
    return 0;
}

效果:

直方图比较:

#include <iostream>
#include <opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
    Mat hsv_1,hsv_2;
    Mat src_1=imread("E:\\opencv\\cv_1\\luff.jpg");
    Mat src_2=imread("E:\\opencv\\cv_1\\luff2.jpg");
    //转为HSV
    cvtColor(src_1,hsv_1,CV_RGB2HSV);
    cvtColor(src_2,hsv_2,CV_RGB2HSV);

    int my_channels[]={0,1};
    //直方图计算
    Mat dst_1,dst_2;
    const int histsize[]={30,32};
    float Hrangs[]={0,180};
    float Srangs[]={0,256};
    const float *ransize[]={Hrangs,Srangs};
    calcHist(&hsv_1,1,my_channels,Mat(),dst_1,2,histsize,ransize,true,false);
    calcHist(&hsv_2,1,my_channels,Mat(),dst_2,2,histsize,ransize,true,false);
    //归一化
    normalize(dst_1,dst_1,0,1,NORM_MINMAX);
    normalize(dst_2,dst_2,0,1,NORM_MINMAX);
    //直方比较
    double result=compareHist(dst_1,dst_2,CV_COMP_CORREL);
    cout<<"相关性:"<<result<<endl;
    result=compareHist(dst_1,dst_2,CV_COMP_CHISQR);
    cout<<"卡方:"<<result<<endl;
    result=compareHist(dst_1,dst_2,CV_COMP_BHATTACHARYYA);
    cout<<"巴氏系数:"<<result<<endl;
    result=compareHist(dst_1,dst_2,CV_COMP_INTERSECT);
    cout<<"相交系数:"<<result<<endl;
    imshow("input",src_1);
    imshow("compare",src_2);


    waitKey(0);
    return 0;
}

对比图:

补充:

函数参数解释:直方图计算:calcHist             //注:转一位博主的注释

CV_EXPORTS void calcHist( const Mat* images, int nimages,
                          const int* channels, InputArray mask,
                          OutputArray hist, int dims, const int* histSize,
                          const float** ranges, bool uniform = true, bool accumulate = false );

 

images:输入图像                                              nimages:输入图像个数

channels:需要计算的直方图的通道                  mask: 掩膜,//不是太懂,直接Mat();

hist: 要承载输出直方图的容器                          dims:需要统计的通道数,这个与channels对应

histSize: 直方图的区间可以理解为x坐标上面的范围          ranges: 统计像素值的区间,同上,理解为y

uniform:默认=true,对直方图归一化                accumulate:在多个图像时,是否累计计算像素值得个数,默认false否

归一化函数:normalize

CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0,
                             int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray());

alpha:归一化后的最小值

beta:归一化后的最大值

norm_type:归一化的模式,一般选择NORM_MINMAX;

归一化的原理也很简单,应该是:在原来未归一化的比例*归一化设置的最大值(也就是beta)

直方图比较compareHist:

CV_EXPORTS_W double compareHist( InputArray H1, InputArray H2, int method );

method有以下几种:

至于取值和什么时候最接近,最相似,网上查一下对应的计算公式,即可得到

1.相关系数的标准(method=CV_COMP_CORREL) 值越大,相关度越高,最大值为1,最小值为0
2 卡方系数的标准(method=CV_COMP_CHISQR) 值越小,相关度越高,最大值无上界,最小值0
3 相交系数的标准(method=CV_COMP_INTERSECT)值越大,相关度越高,最小值为0
4 巴氏系数的标准(method=CV_COMP_BHATTACHARYYA)值越小,相关度越高,最大值为1,最小值为0

 

RGB与HSV:

详情转:

https://blog.csdn.net/yangdashi888/article/details/53782481

我这里就简单讲一下注意点:

HSV:H->色相(hue),S->饱和度(saturation),V->明暗(value)

HSV更适合我们常规,网上有很多关于它的图像,呈圆锥状

H取值范围0~360度,S取值范围0~1,V取值范围0~255;

但不同的软件进行量化的取值范围是不同的,例如PS软件里的h取值为0-360、s取值为0-1、v取值为0-1.而opencv里cvSplit使用的图像是32F则其取值是h为0-360、s取值为0-1、v取值为0-255。如果是8UC则取值范围是h为0-180、s取值为0-255、v取值是0-255.  其中h色调对图像的分辨是很准的,这也就是为什么这样写:

    const int histsize[]={30,30};
    float Hrangs[]={0,180};
    float Srangs[]={0,256};
    const float *ransize[]={Hrangs,Srangs};
    calcHist(&hsv_1,1,my_channels,Mat(),dst_1,2,histsize,ransize,true,false);
    //H,S两个通道,取值分贝是0~180,0~256

 

 

 

 

 

 

 

 

 

 

OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理和分析功能。图像缩放是OpenCV中常用的一种图像处理技术,它可以改变图像的尺寸大小。 直方图是一种统计图形,用于表示一组数据的变化情况。在图像处理中,直方图描述了图像中像素值的分布情况。基于直方图的算法可以用来比较图像之间的相似度。 图像缩放对直方图算法相似度的影响是显著的。当图像进行缩放时,像素值的分布发生变化,直方图也会相应地改变。因此,在缩放后的图像上计算的直方图与原图像的直方图将不再相同。 图像缩放会导致直方图的形状发生变化,进而影响直方图算法的相似度度量结果。在缩小图像尺寸的情况下,直方图的分布信息可能会损失,因此算法的相似度度量可能会有所下降。而在放大图像尺寸的情况下,直方图的形状可能会变得更加平滑,导致算法相似度度量结果可能较为接近。 为了解决图像缩放对直方图算法相似度的影响,可以考虑在进行缩放操作之前,对图像进行预处理。例如,可以进行直方图均衡化或直方图匹配等操作,使得图像的直方图分布更加平衡或与目标直方图更加相似。这样,在缩放后计算直方图相似度时,结果会更加准确和可靠。 总之,图像缩放对直方图算法相似度有一定的影响,需要在实际应用中综合考虑图像的特点和需求,进行适当的预处理和调整,以得到准确和可靠的相似度度量结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值