《学习OpenCV》第七章直方图(练习7.2)

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

分别给定2维、8维、16维、32维、256维进行运算


#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

#define cvQueryHistValue_1D( hist, idx0 )   cvGetReal1D( (hist)->bins, (idx0) )
#define cvQueryHistValue_2D( hist, idx0 , idx1 )   cvGetReal2D( (hist)->bins, (idx0) , (idx1))
#define binNum 2   //   每一位幅bin的大小

/*画直方图*/
void DisplayHistogram(CvHistogram * hist , char * windName)
{
    if(!hist || !windName)
    {
        return;
    }
    int scale = 100; //缩放比例
    int h_bins = hist->mat.dim[0].size;
    int s_bins = hist->mat.dim[1].size;
    IplImage * histImg = cvCreateImage(cvSize(h_bins * scale , s_bins * scale), 8, 3);
    cvSetZero(histImg);
    //显示直方图
    float max_value = 0;
    float bin_value = 0;
    int   intensity = 0;
    cvGetMinMaxHistValue(hist, 0, &max_value,0,0);
    for(int i = 0;i<h_bins;i++)
    {
        for(int j = 0;j<s_bins;j++)
        {
            bin_value = cvQueryHistValue_2D( hist, i, j);
            intensity = cvRound(bin_value * 255 / max_value);
            cvRectangle(histImg, cvPoint(i*scale, j*scale), cvPoint((i+1)*scale-1, (j+1)*scale-1),
                                                CV_RGB(intensity, intensity, intensity),CV_FILLED);
            
        }
    }
    cvNamedWindow(windName);
    cvShowImage(windName, histImg);

}


int main(int argc, const char * argv[]) {
    /*1、加载图片*/
    const char filename1[] = "/Users/linwang/Downloads/hand1.jpg";
    const char filename2[] = "/Users/linwang/Downloads/hand2.jpg";
    const char filename3[] = "/Users/linwang/Downloads/hand3.jpg";
    IplImage * Img_hand1 = cvLoadImage(filename1);
    IplImage * Img_hand2 = cvLoadImage(filename2);
    IplImage * Img_hand3 = cvLoadImage(filename3);
    
    /*2、缩放0.3倍*/
    float scale = 0.3;
    IplImage * dst_hand1 = cvCreateImage(cvSize(Img_hand1->width * scale, Img_hand1->height * scale),
                                         Img_hand1->depth, Img_hand1->nChannels);
    
    IplImage * dst_hand2 = cvCreateImage(cvSize(Img_hand2->width * scale, Img_hand2->height * scale),
                                         Img_hand2->depth, Img_hand2->nChannels);
    
    IplImage * dst_hand3 = cvCreateImage(cvSize(Img_hand3->width * scale, Img_hand3->height * scale),
                                         Img_hand3->depth, Img_hand3->nChannels);
    
    cvResize(Img_hand1, dst_hand1);
    cvResize(Img_hand2, dst_hand2);
    cvResize(Img_hand3, dst_hand3);
    
    /*3、显示当前的图片*/
    cvNamedWindow("Hand1");
    cvNamedWindow("Hand2");
    cvNamedWindow("Hand3");
    
    cvShowImage("Hand1", dst_hand1);
    cvShowImage("Hand2", dst_hand2);
    cvShowImage("Hand3", dst_hand3);
    
    /*4、分别创建三幅手势图像的HSV空间图像单元*/
    IplImage * Hsv_hand1 = cvCreateImage(cvGetSize(dst_hand1), 8, 3);
    IplImage * Hsv_hand2 = cvCreateImage(cvGetSize(dst_hand2), 8, 3);
    IplImage * Hsv_hand3 = cvCreateImage(cvGetSize(dst_hand3), 8, 3);
    cvSetZero(Hsv_hand1);
    cvSetZero(Hsv_hand2);
    cvSetZero(Hsv_hand3);
    
    /*5、颜色阈转换,从GRB到HSV*/
    cvCvtColor(dst_hand1, Hsv_hand1, CV_RGB2HSV);
    cvCvtColor(dst_hand2, Hsv_hand2, CV_RGB2HSV);
    cvCvtColor(dst_hand3, Hsv_hand3, CV_RGB2HSV);
    
    /*6、分别创建hsv的三通道*/
    IplImage * h_plane1 = cvCreateImage(cvGetSize(dst_hand1), 8, 1);
    IplImage * h_plane2 = cvCreateImage(cvGetSize(dst_hand2), 8, 1);
    IplImage * h_plane3 = cvCreateImage(cvGetSize(dst_hand3), 8, 1);

    IplImage * s_plane1 = cvCreateImage(cvGetSize(dst_hand1), 8, 1);
    IplImage * s_plane2 = cvCreateImage(cvGetSize(dst_hand2), 8, 1);
    IplImage * s_plane3 = cvCreateImage(cvGetSize(dst_hand3), 8, 1);
    
    IplImage * v_plane1 = cvCreateImage(cvGetSize(dst_hand1), 8, 1);
    IplImage * v_plane2 = cvCreateImage(cvGetSize(dst_hand2), 8, 1);
    IplImage * v_plane3 = cvCreateImage(cvGetSize(dst_hand3), 8, 1);
    
    cvSplit(Hsv_hand1, h_plane1, s_plane1, v_plane1, 0);
    cvSplit(Hsv_hand2, h_plane2, s_plane2, v_plane2, 0);
    cvSplit(Hsv_hand3, h_plane3, s_plane3, v_plane3, 0);
    
    /*7、准备床架吧直方图hist*/
    IplImage * planes1[] = {h_plane1,s_plane1};
    IplImage * planes2[] = {h_plane2,s_plane2};
    IplImage * planes3[] = {h_plane3,s_plane3};
    
    int h_bins1 = binNum;
    int h_bins2 = binNum;
    int h_bins3 = binNum;
    
    int s_bins1 = binNum;
    int s_bins2 = binNum;
    int s_bins3 = binNum;
    
    CvHistogram * hist1;
    CvHistogram * hist2;
    CvHistogram * hist3;
    
    int hist_size1[] = {h_bins1,s_bins1};
    int hist_size2[] = {h_bins2,s_bins2};
    int hist_size3[] = {h_bins3,s_bins3};
    
    float h_ranges1[] = {0,180};
    float h_ranges2[] = {0,180};
    float h_ranges3[] = {0,180};
    
    float s_ranges1[] = {0,255};
    float s_ranges2[] = {0,255};
    float s_ranges3[] = {0,255};
    
    float * ranges1[] = {h_ranges1,s_ranges1};
    float * ranges2[] = {h_ranges2,s_ranges2};
    float * ranges3[] = {h_ranges3,s_ranges3};
    
    hist1 = cvCreateHist(2, hist_size1, CV_HIST_ARRAY,ranges1,1);
    hist2 = cvCreateHist(2, hist_size2, CV_HIST_ARRAY,ranges2,1);
    hist3 = cvCreateHist(2, hist_size3, CV_HIST_ARRAY,ranges3,1);
    
    /*8、计算直方图并做归一化*/
    cvCalcHist(planes1, hist1 , 0 ,0);
    cvCalcHist(planes2, hist2 , 0 ,0);
    cvCalcHist(planes3, hist3 , 0 ,0);
    
    cvNormalizeHist(hist1, 1.0);
    cvNormalizeHist(hist2, 1.0);
    cvNormalizeHist(hist3, 1.0);
    
    /*9、显示各种直方图的对比结果*/
    cout<<"Bins = "<<binNum<<endl;
    double dist1_to_2[4] = {0.0};
    double dist1_to_3[4] = {0.0};
    double dist2_to_3[4] = {0.0};
    char *hist_method[4] = {"相关","卡方","直方图相交","Bhattacharyya距离"};
   //依次进行"相关","卡方","直方图相交","Bhattacharyya距离" 比较操作,并显示结果
    for(int i = 0;i<4;i++)
    {
        dist1_to_2[i] = cvCompareHist(hist1, hist2, i);
        cout<<"Method : "<<hist_method[i]<<"->图像1和图像2的匹配结果-> "<<dist1_to_2[i]<<endl;
    }
    
    for(int i = 0;i<4;i++)
    {
        dist1_to_3[i] = cvCompareHist(hist1, hist3, i);
        cout<<"Method : "<<hist_method[i]<<"->图像1和图像3的匹配结果-> "<<dist1_to_3[i]<<endl;
    }
    
    for(int i = 0;i<4;i++)
    {
        dist2_to_3[i] = cvCompareHist(hist2, hist3, i);
        cout<<"Method : "<<hist_method[i]<<"->图像2和图像3的匹配结果-> "<<dist2_to_3[i]<<endl;
    }
    
    /*10、利用直方图显示各种匹配结果*/
    cout<<hist1->mat.dim[0].size<<endl;
    cout<<hist1->mat.dim[1].size<<endl;
    DisplayHistogram(hist1, "hist1");
    DisplayHistogram(hist2, "hist2");
    DisplayHistogram(hist3, "hist3");
    cvWaitKey(0);
    
    cvReleaseHist(&hist1);
    cvReleaseHist(&hist2);
    cvReleaseHist(&hist3);
    cvDestroyWindow("Hand1");
    cvDestroyWindow("Hand2");
    cvDestroyWindow("Hand3");
    cvReleaseImage(&Img_hand1);
    cvReleaseImage(&Img_hand2);
    cvReleaseImage(&Img_hand3);
    cvReleaseImage(&dst_hand1);
    cvReleaseImage(&dst_hand2);
    cvReleaseImage(&dst_hand3);
    cvReleaseImage(&Hsv_hand1);
    cvReleaseImage(&Hsv_hand2);
    cvReleaseImage(&Hsv_hand3);
    cvReleaseImage(&h_plane1);
    cvReleaseImage(&h_plane2);
    cvReleaseImage(&h_plane3);
    cvReleaseImage(&s_plane1);
    cvReleaseImage(&s_plane2);
    cvReleaseImage(&s_plane3);
    cvReleaseImage(&v_plane1);
    cvReleaseImage(&v_plane2);
    cvReleaseImage(&v_plane3);
    return 1;
    
}





2维



8维



16维


32维:


256维


发布了192 篇原创文章 · 获赞 14 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/u011559236/article/details/78713703