8bin的个数对直方图匹配产生的影响

8bin的个数对直方图匹配产生的影响

给定三幅在书中讨论的不同光照条件下的手图像,利用cvCalcHist()来获得室内拍照的手的肤色直方图。

 1. 依次尝试用少量的bin(如每维有2个),中等数目的bin(每维有16个)和很多bin(每维256个),然后对各种光线下的图像运行匹配程序(使用所有的直方图匹配方法);
 2. 现在加上每维为8个和32个bin,在各种光线条件下进行匹配;

程序中三幅图像已经过处理,依次比前一幅亮度增加40,具体代码如下:


#include <cv.h>
#include <highgui.h>  
#include <stdlib.h>  
#include <stdio.h> 
#include <math.h>

using namespace std;

int main(int argc, char* argv[])
{
    IplImage* src1, *src2, *src3,*Imask, *hsv1, *hsv2,*hsv3;                //源图像 HSV格式图像
    //src1 src2 亮度较前一张增加了10 src2 src3 亮度较前一张增加了40
    if (!(src1 = cvLoadImage("D:\\Template\\OpenCV\\Template52_hue-saturation_Compare\\Debug\\hand1.jpg")))
        return -1;
    if (!(src2 = cvLoadImage("D:\\Template\\OpenCV\\Template52_hue-saturation_Compare\\Debug\\hand3.jpg")))
        return -2;
    if (!(src3 = cvLoadImage("D:\\Template\\OpenCV\\Template52_hue-saturation_Compare\\Debug\\hand5.jpg")))
        return -3;
    //Mask为手掌掩码 过滤掉其他背景 只分析手掌颜色直方图 可略
    if (!(Imask = cvLoadImage("D:\\Template\\OpenCV\\Template52_hue-saturation_Compare\\Debug\\Imask.jpg", 
        CV_LOAD_IMAGE_GRAYSCALE)))
        return -4;

    hsv1 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);
    hsv2 = cvCreateImage(cvGetSize(src2), src2->depth, src2->nChannels);
    hsv3 = cvCreateImage(cvGetSize(src3), src3->depth, src3->nChannels);

    cvCvtColor(src1, hsv1, CV_BGR2HSV);     //源图像->HSV格式图像
    cvCvtColor(src2, hsv2, CV_BGR2HSV);     //源图像->HSV格式图像
    cvCvtColor(src3, hsv3, CV_BGR2HSV);     //源图像->HSV格式图像

    //色调(hue) 饱和度(saturation) 明度(value)
    IplImage *h_plane_1 = cvCreateImage(cvSize(hsv1->width, hsv1->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_1 = cvCreateImage(cvSize(hsv1->width, hsv1->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_1 = cvCreateImage(cvSize(hsv1->width, hsv1->height), IPL_DEPTH_8U, 1);

    IplImage *h_plane_2 = cvCreateImage(cvSize(hsv2->width, hsv2->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_2 = cvCreateImage(cvSize(hsv2->width, hsv2->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_2 = cvCreateImage(cvSize(hsv2->width, hsv2->height), IPL_DEPTH_8U, 1);

    IplImage *h_plane_3 = cvCreateImage(cvSize(hsv3->width, hsv3->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_3 = cvCreateImage(cvSize(hsv3->width, hsv3->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_3 = cvCreateImage(cvSize(hsv3->width, hsv3->height), IPL_DEPTH_8U, 1);

    IplImage *planes1[] = { h_plane_1, s_plane_1 };                     //色相饱和度数组
    IplImage *planes2[] = { h_plane_2, s_plane_2 };                     //色相饱和度数组
    IplImage *planes3[] = { h_plane_3, s_plane_3 };                     //色相饱和度数组

    cvCvtPixToPlane(hsv1, h_plane_1, s_plane_1, v_plane_1, NULL);       //图像分割
    cvCvtPixToPlane(hsv2, h_plane_2, s_plane_2, v_plane_2, NULL);       //图像分割
    cvCvtPixToPlane(hsv3, h_plane_3, s_plane_3, v_plane_3, NULL);       //图像分割
    //cvSplit(hsv, h_plane, s_plane, v_plane, NULL);

    for (int i = 0; i < 5; i++)
    {
        //建立直方图
        CvHistogram *hist1, *hist2, *hist3;

        int bins=0;
        int h_bins_1 = 2, s_bins_1 = 2;
        int h_bins_2 = 8, s_bins_2 = 8;
        int h_bins_3 = 16, s_bins_3 = 16;
        int h_bins_4 = 32, s_bins_4 = 32;
        int h_bins_5 = 256, s_bins_5 = 256;

        int hist_size_1[] = { h_bins_1, s_bins_1 }; //对应维数包含bins个数的数组
        int hist_size_2[] = { h_bins_2, s_bins_2 }; //对应维数包含bins个数的数组
        int hist_size_3[] = { h_bins_3, s_bins_3 }; //对应维数包含bins个数的数组
        int hist_size_4[] = { h_bins_4, s_bins_4 }; //对应维数包含bins个数的数组
        int hist_size_5[] = { h_bins_5, s_bins_5 }; //对应维数包含bins个数的数组

        float h_ranges[] = { 0, 180 };              //H通道划分范围 饱和度0-180
        float s_ranges[] = { 0, 255 };              //S通道划分范围
        float* ranges[] = { h_ranges, s_ranges };   //划分范围数对, 均匀bin,range只要最大最小边界
        //bins 2*2
        if (i == 0)
        {
            hist1 = cvCreateHist(2, hist_size_1, CV_HIST_ARRAY, ranges, 1);
            hist2 = cvCreateHist(2, hist_size_1, CV_HIST_ARRAY, ranges, 1);
            hist3 = cvCreateHist(2, hist_size_1, CV_HIST_ARRAY, ranges, 1);
            bins = h_bins_1;
        }
        //bins 8*8
        if (i == 1)
        {
            hist1 = cvCreateHist(2, hist_size_2, CV_HIST_ARRAY, ranges, 1);
            hist2 = cvCreateHist(2, hist_size_2, CV_HIST_ARRAY, ranges, 1);
            hist3 = cvCreateHist(2, hist_size_2, CV_HIST_ARRAY, ranges, 1);
            bins = h_bins_2;
        }
        //bins 16*16
        if (i == 2)
        {
            hist1 = cvCreateHist(2, hist_size_3, CV_HIST_ARRAY, ranges, 1);
            hist2 = cvCreateHist(2, hist_size_3, CV_HIST_ARRAY, ranges, 1);
            hist3 = cvCreateHist(2, hist_size_3, CV_HIST_ARRAY, ranges, 1);
            bins = h_bins_3;
        }
        //bins 32*32
        if (i == 3)
        {
            hist1 = cvCreateHist(2, hist_size_4, CV_HIST_ARRAY, ranges, 1);
            hist2 = cvCreateHist(2, hist_size_4, CV_HIST_ARRAY, ranges, 1);
            hist3 = cvCreateHist(2, hist_size_4, CV_HIST_ARRAY, ranges, 1);
            bins = h_bins_4;
        }
        //bins 256*256
        if (i == 4)
        {
            hist1 = cvCreateHist(2, hist_size_5, CV_HIST_ARRAY, ranges, 1);
            hist2 = cvCreateHist(2, hist_size_5, CV_HIST_ARRAY, ranges, 1);
            hist3 = cvCreateHist(2, hist_size_5, CV_HIST_ARRAY, ranges, 1);
            bins = h_bins_5;
        }

        //创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图)
        cvCalcHist(planes1, hist1, 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)
        cvCalcHist(planes2, hist2, 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)
        cvCalcHist(planes3, hist3, 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)
        //cvCalcHist(planes1, hist1, 0, Imask);     //计算直方图(图像,直方图结构,不累加,掩码)
        //cvCalcHist(planes2, hist2, 0, Imask);     //计算直方图(图像,直方图结构,不累加,掩码)
        //cvCalcHist(planes3, hist3, 0, Imask);     //计算直方图(图像,直方图结构,不累加,掩码)


        cvNormalizeHist(hist1, 1.0);            //直方图归一化
        cvNormalizeHist(hist2, 1.0);            //直方图归一化
        cvNormalizeHist(hist3, 1.0);            //直方图归一化

        //比较直方图
        for (int j = 0; j < 4; j++)
        {
            double value1 = cvCompareHist(hist1, hist2, j);         //相关方式比较
            double value2 = cvCompareHist(hist1, hist3, j);         //相关方式比较
                if (j == 0)
                {
                    printf("Bins:%d*%d ,Hist1 & Hist2 ,CORREL: %lf;\n", bins, bins, value1);
                    printf("Bins:%d*%d ,Hist1 & Hist3 ,CORREL: %lf;\n", bins, bins, value2);
                }
                if (j == 1)
                {
                    printf("Bins:%d*%d ,Hist1 & Hist2 ,CHISQR: %lf;\n", bins, bins, value1);
                    printf("Bins:%d*%d ,Hist1 & Hist3 ,CHISQR: %lf;\n", bins, bins, value2);
                }
                if (j == 2)
                {
                    printf("Bins:%d*%d ,Hist1 & Hist2 ,INTERSECT: %lf;\n", bins, bins, value1);
                    printf("Bins:%d*%d ,Hist1 & Hist3 ,INTERSECT: %lf;\n", bins, bins, value2);
                }
                if (j == 3)
                {
                    printf("Bins:%d*%d ,Hist1 & Hist2 ,BHATTACHARYYA: %lf;\n", bins, bins, value1);
                    printf("Bins:%d*%d ,Hist1 & Hist3 ,BHATTACHARYYA: %lf;\n", bins, bins, value2);
                }   
        }
        cvReleaseHist(&hist1);
        cvReleaseHist(&hist2);
        cvReleaseHist(&hist3);

        cout << endl;
    }

    cvNamedWindow("SRC1", 1);
    cvNamedWindow("SRC2", 1);
    cvNamedWindow("SRC3", 1);
    cvNamedWindow("IMASK", 1);

    cvShowImage("SRC1", src1);
    cvShowImage("SRC2", src2);
    cvShowImage("SRC3", src3);
    cvShowImage("IMASK", Imask);

    cvWaitKey(0);
    system("pause");

    cvReleaseImage(&src1);
    cvReleaseImage(&src2);
    cvReleaseImage(&src3);
    cvReleaseImage(&Imask);
    cvReleaseImage(&hsv1);
    cvReleaseImage(&hsv2);
    cvReleaseImage(&hsv3);
    cvReleaseImage(&h_plane_1);
    cvReleaseImage(&s_plane_1);
    cvReleaseImage(&v_plane_1);
    cvReleaseImage(&h_plane_2);
    cvReleaseImage(&s_plane_2);
    cvReleaseImage(&v_plane_2);
    cvReleaseImage(&h_plane_3);
    cvReleaseImage(&s_plane_3);
    cvReleaseImage(&v_plane_3);

    cvDestroyAllWindows();
}

运行结果:
这里写图片描述
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 直方图中的 bin 宽度是指将整个数据集划分为多个相等的区间(或者称为箱子),每个区间的宽度相等。在直方图中,每个 bin 的高度表示数据集中落在该区间内的数据数量,而每个 bin 的宽度则表示该区间的取值范围。通常情况下,bin 的宽度需要根据数据的分布情况进行合理的选择,以便更好地展示数据的特征。如果 bin 的宽度过小,则直方图会过于详细,缺乏整体性;如果 bin 的宽度过大,则直方图会过于粗略,无法反映数据的细节。 ### 回答2: 直方图bin的宽度指的是数据的分组间隔或者区间大小。直方图是一种用于表示数据分布情况的图形方式,在其上将数据按照一定的区间划分为不同的组,每个组就是一个bin。而每个bin的宽度表示了该区间范围内数据的大小。 在绘制直方图时,通常需要选择合适的bin宽度来展示数据的分布情况。如果bin宽度过小,将导致图形细节过多、过于密集;而如果bin宽度过大,则无法准确地反映数据的分布情况。因此,选择合适的bin宽度非常重要。 确定bin宽度的时候,可以考虑以下几个因素:数据的范围、数据的分布形态、数据点的数量等。一般来说,可以通过试探不同的bin宽度,观察直方图的形状和数据分布情况,以找到一个使得数据能够被清晰地展示出来的bin宽度。 总之,直方图bin宽度是指用来划分数据的区间大小,好的bin宽度可以更好地展示数据的分布情况,提供对数据的直观认识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值