您现在的位置:首页 > 教案格式 > 正文

第七章 学习OpenCV(7)

2019-07-04 21:05 网络整理 教案网

运行结果如下图:

光照条件判定

在三种条件下建立两类肤色模板直方图。

 1. 从室内、室外阴影和室外阳光下得到的第一类直方图作为模型,用其中每一个分别跟第二类图进行B距离测试,检验肤色匹配效果;
 2. 利用(1)中设计的“场景检测器”确定要使用何种直方图模型:室内、室外阴影还是室外阳光;进行其他匹配方式,检验效果;

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

直方图匹配原理_envi直方图匹配_匹配滤波原理

#include <cv.h>
#include <highgui.h>  
#include <stdlib.h>  
#include <stdio.h> 
#include <math.h>
using namespace std;
int main(int argc, char* argv[])
{
    //源图像 HSV格式图像
    IplImage* src1, *src2, *src3, *src4, *src5, *src6, *Imask, *hsv1, *hsv2, *hsv3, *hsv4,*hsv5, *hsv6;     
    //src1 src2 亮度相同  src3 src4亮度相同 src5 src6亮度相同  每级依次增加20
    //模板 室内
    if (!(src1 = cvLoadImage("D:\\Template\\OpenCV\\Template55_V_HS_Compare\\Debug\\handdd.jpg")))
        return -1;
    //测试 室内
    if (!(src2 = cvLoadImage("D:\\Template\\OpenCV\\Template55_V_HS_Compare\\Debug\\handd.jpg")))
        return -2;
    //模板 室外阴影
    if (!(src3 = cvLoadImage("D:\\Template\\OpenCV\\Template55_V_HS_Compare\\Debug\\handdd_out.jpg")))
        return -3;
    //测试 室外阴影
    if (!(src4 = cvLoadImage("D:\\Template\\OpenCV\\Template55_V_HS_Compare\\Debug\\handd_out.jpg")))
        return -4;
    //模板 室外光照
    if (!(src5 = cvLoadImage("D:\\Template\\OpenCV\\Template55_V_HS_Compare\\Debug\\handdd_out_sun.jpg")))
        return -5;
    if (!(src6 = cvLoadImage("D:\\Template\\OpenCV\\Template55_V_HS_Compare\\Debug\\handd_out_sun.jpg")))
        return -6;
    //Mask为手掌掩码 过滤掉其他背景 只分析手掌颜色直方图 可略
    if (!(Imask = cvLoadImage("D:\\Template\\OpenCV\\Template54_value_Compare\\Debug\\Imask.jpg", 
        CV_LOAD_IMAGE_GRAYSCALE)))
        return -7;
    hsv1 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);
    hsv2 = cvCreateImage(cvGetSize(src2), src2->depth, src2->nChannels);
    hsv3 = cvCreateImage(cvGetSize(src3), src3->depth, src3->nChannels);
    hsv4 = cvCreateImage(cvGetSize(src4), src4->depth, src4->nChannels);
    hsv5 = cvCreateImage(cvGetSize(src5), src5->depth, src5->nChannels);
    hsv6 = cvCreateImage(cvGetSize(src6), src6->depth, src6->nChannels);
    cvCvtColor(src1, hsv1, CV_BGR2HSV);     //源图像->HSV格式图像
    cvCvtColor(src2, hsv2, CV_BGR2HSV);     //源图像->HSV格式图像
    cvCvtColor(src3, hsv3, CV_BGR2HSV);     //源图像->HSV格式图像
    cvCvtColor(src4, hsv4, CV_BGR2HSV);     //源图像->HSV格式图像
    cvCvtColor(src5, hsv5, CV_BGR2HSV);     //源图像->HSV格式图像
    cvCvtColor(src6, hsv6, 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 *h_plane_4 = cvCreateImage(cvSize(hsv4->width, hsv4->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_4 = cvCreateImage(cvSize(hsv4->width, hsv4->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_4 = cvCreateImage(cvSize(hsv4->width, hsv4->height), IPL_DEPTH_8U, 1);
    IplImage *h_plane_5 = cvCreateImage(cvSize(hsv5->width, hsv5->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_5 = cvCreateImage(cvSize(hsv5->width, hsv5->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_5 = cvCreateImage(cvSize(hsv5->width, hsv5->height), IPL_DEPTH_8U, 1);
    IplImage *h_plane_6 = cvCreateImage(cvSize(hsv6->width, hsv6->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_6 = cvCreateImage(cvSize(hsv6->width, hsv6->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_6 = cvCreateImage(cvSize(hsv6->width, hsv6->height), IPL_DEPTH_8U, 1);
    IplImage *planes1[] = { v_plane_1 };                        //亮度数组
    IplImage *planes2[] = { v_plane_2 };                        
    IplImage *planes3[] = { v_plane_3 };                        
    IplImage *planes4[] = { v_plane_4 };                        
    IplImage *planes5[] = { v_plane_5 };                        
    IplImage *planes6[] = { v_plane_6 };                        
    IplImage *planes7[] = { h_plane_1, s_plane_1 };             //色相饱和度数组
    IplImage *planes8[] = { h_plane_2, s_plane_2 };
    IplImage *planes9[] = { h_plane_3, s_plane_3 };
    IplImage *planes10[] = { h_plane_4, s_plane_4 };
    IplImage *planes11[] = { h_plane_5, s_plane_5 };
    IplImage *planes12[] = { h_plane_6, s_plane_6 };
    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);       //图像分割
    cvCvtPixToPlane(hsv4, h_plane_4, s_plane_4, v_plane_4, NULL);       //图像分割
    cvCvtPixToPlane(hsv5, h_plane_5, s_plane_5, v_plane_5, NULL);       //图像分割
    cvCvtPixToPlane(hsv6, h_plane_6, s_plane_6, v_plane_6, NULL);       //图像分割
    //cvSplit(hsv, h_plane, s_plane, v_plane, NULL);
    //建立直方图 v直方图:筛选合适的光照条件  hs直方图:肤色匹配
    CvHistogram *hist_v[6], *hist_h_s[6];
    int v_bins = 32;
    int hist_v_size[] = { v_bins };             //对应维数包含bins个数的数组
    int h_bins = 30, s_bins = 32;
    int hist_h_s_size[] = { h_bins, s_bins };   //对应维数包含bins个数的数组
    float v_range[] = { 0, 255 };       //V通道划分范围
    float* v_ranges[] = { v_range };    //划分范围数对, ****均匀bin,range只要最大最小边界
    float h_ranges[] = { 0, 180 };                  //H通道划分范围 饱和度0-180
    float s_ranges[] = { 0, 255 };                  //S通道划分范围
    float* h_s_ranges[] = { h_ranges, s_ranges };   //划分范围数对, ****均匀bin,range只要最大最小边界
    //创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图)
    hist_v[0] = cvCreateHist(1, hist_v_size, CV_HIST_ARRAY, v_ranges, 1);
    hist_v[1] = cvCreateHist(1, hist_v_size, CV_HIST_ARRAY, v_ranges, 1);
    hist_v[2] = cvCreateHist(1, hist_v_size, CV_HIST_ARRAY, v_ranges, 1);
    hist_v[3] = cvCreateHist(1, hist_v_size, CV_HIST_ARRAY, v_ranges, 1);
    hist_v[4] = cvCreateHist(1, hist_v_size, CV_HIST_ARRAY, v_ranges, 1);
    hist_v[5] = cvCreateHist(1, hist_v_size, CV_HIST_ARRAY, v_ranges, 1);
    hist_h_s[0] = cvCreateHist(1, hist_h_s_size, CV_HIST_ARRAY, h_s_ranges, 1);
    hist_h_s[1] = cvCreateHist(1, hist_h_s_size, CV_HIST_ARRAY, h_s_ranges, 1);
    hist_h_s[2] = cvCreateHist(1, hist_h_s_size, CV_HIST_ARRAY, h_s_ranges, 1);
    hist_h_s[3] = cvCreateHist(1, hist_h_s_size, CV_HIST_ARRAY, h_s_ranges, 1);
    hist_h_s[4] = cvCreateHist(1, hist_h_s_size, CV_HIST_ARRAY, h_s_ranges, 1);
    hist_h_s[5] = cvCreateHist(1, hist_h_s_size, CV_HIST_ARRAY, h_s_ranges, 1);
    //创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图)
    cvCalcHist(planes1, hist_v[0], 0, Imask);   //计算直方图(图像,直方图结构,不累加,mask仅采集手掌)
    cvCalcHist(planes2, hist_v[1], 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes3, hist_v[2], 0, Imask);   //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes4, hist_v[3], 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes5, hist_v[4], 0, Imask);   //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes6, hist_v[5], 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes7 , hist_h_s[0], 0, 0);//计算直方图(图像,直方图结构,不累加,mask仅采集手掌)
    cvCalcHist(planes8 , hist_h_s[1], 0, 0);    //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes9 , hist_h_s[2], 0, 0);//计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes10, hist_h_s[3], 0, 0);    //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes11, hist_h_s[4], 0, 0);//计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes12, hist_h_s[5], 0, 0);    //计算直方图(图像,直方图结构,不累加,掩码)
    //直方图归一化
    cvNormalizeHist(hist_v[0], 1.0);
    cvNormalizeHist(hist_v[1], 1.0);
    cvNormalizeHist(hist_v[2], 1.0);
    cvNormalizeHist(hist_v[3], 1.0);
    cvNormalizeHist(hist_v[4], 1.0);
    cvNormalizeHist(hist_v[5], 1.0);
    cvNormalizeHist(hist_h_s[0], 1.0);
    cvNormalizeHist(hist_h_s[1], 1.0);
    cvNormalizeHist(hist_h_s[2], 1.0);
    cvNormalizeHist(hist_h_s[3], 1.0);
    cvNormalizeHist(hist_h_s[4], 1.0);
    cvNormalizeHist(hist_h_s[5], 1.0);
    for (int i = 1; i < 4; i++)
    {
        double min = 0,max=0;
        CvPoint point;
        CvMat* mat = cvCreateMat(1, 3, CV_64FC1);
        double value1 = cvCompareHist(hist_v[0], hist_v[2 * i - 1], CV_COMP_BHATTACHARYYA); //B距离比较
        double value2 = cvCompareHist(hist_v[2], hist_v[2 * i - 1], CV_COMP_BHATTACHARYYA); //B距离比较
        double value3 = cvCompareHist(hist_v[4], hist_v[2 * i - 1], CV_COMP_BHATTACHARYYA); //B距离比较
        printf("第 %d 幅测试图像与亮度模板比较值:\n",i);
        printf(" 室内:%lf, 室外:%lf, 室外阳光:%lf\n", value1, value2, value3);
        cvSet1D(mat, 0, cvScalar(value1));
        cvSet1D(mat, 1, cvScalar(value2));
        cvSet1D(mat, 2, cvScalar(value3));
        cvMinMaxLoc(mat, &min, &max, &point, NULL, NULL);
        switch (point.x)
        {
            case 0:
                printf("第 %d 幅测试图像与亮度模板比较值最小值:%lf\n判定在室内环境下拍摄.\n", i, min);
                printf("应当选择室内环境肤色模板进行肤色匹配:\n");
                //不同比较方式的结果
                for (int j = 0; j < 4; j++)
                {
                    double h_s_value = cvCompareHist(hist_h_s[0], hist_h_s[2 * i - 1], j);
                    if (j == 0)
                    {
                        printf("  相关CV_COMP_CORREL: %lf;\n",h_s_value);
                    }
                    if (j == 1)
                    {
                        printf("  卡方CV_COMP_CHISQR: %lf;\n",h_s_value);
                    }
                    if (j == 2)
                    {
                        printf("  相交CV_COMP_INTERSECT: %lf;\n",h_s_value);
                    }
                    if (j == 3)
                    {
                        printf("  B距离CV_CCOMP_BHATTACHARYYA: %lf;\n",h_s_value);
                    }
                }
                break;
            case 1:
                printf("第 %d 幅测试图像与亮度模板比较值最小值:%lf\n判定在室外环境下拍摄.\n", i, min);
                printf("应当选择室外环境肤色模板进行肤色匹配:\n");
                //不同比较方式的结果
                for (int j = 0; j < 4; j++)
                {
                    double h_s_value = cvCompareHist(hist_h_s[2], hist_h_s[2 * i - 1], j);
                    if (j == 0)
                    {
                        printf("  相关CV_COMP_CORREL: %lf;\n", h_s_value);
                    }
                    if (j == 1)
                    {
                        printf("  卡方CV_COMP_CHISQR: %lf;\n", h_s_value);
                    }
                    if (j == 2)
                    {
                        printf("  相交CV_COMP_INTERSECT: %lf;\n", h_s_value);
                    }
                    if (j == 3)
                    {
                        printf("  B距离CV_CCOMP_BHATTACHARYYA: %lf;\n", h_s_value);
                    }
                }
                break;
            case 2:
                printf("第 %d 幅测试图像与亮度模板比较值最小值:%lf\n判定在室外阳光下拍摄.\n", i, min);
                printf("应当选择室外阳光肤色模板进行肤色匹配:\n");
                //不同比较方式的结果
                for (int j = 0; j < 4; j++)
                {
                    double h_s_value = cvCompareHist(hist_h_s[4], hist_h_s[2 * i - 1], j);
                    if (j == 0)
                    {
                        printf("  相关CV_COMP_CORREL: %lf;\n", h_s_value);
                    }
                    if (j == 1)
                    {
                        printf("  卡方CV_COMP_CHISQR: %lf;\n", h_s_value);
                    }
                    if (j == 2)
                    {
                        printf("  相交CV_COMP_INTERSECT: %lf;\n", h_s_value);
                    }
                    if (j == 3)
                    {
                        printf("  B距离CV_CCOMP_BHATTACHARYYA: %lf;\n", h_s_value);
                    }
                }
                break;
        }
        cvReleaseMat(&mat);
        cout << endl;
    }
    cvNamedWindow("Room_model", 1);
    cvNamedWindow("Out_model", 1);
    cvNamedWindow("Out_Sun_model", 1);
    cvNamedWindow("IMASK", 1);
    cvNamedWindow("Room_test_第1幅", 1);
    cvNamedWindow("Out_test_第2幅", 1);
    cvNamedWindow("Out_Sun_test_第3幅", 1);
    cvShowImage("Room_model", src1);
    cvShowImage("Out_model", src3);
    cvShowImage("Out_Sun_model", src5);
    cvShowImage("IMASK", Imask);
    cvShowImage("Room_test_第1幅", src2);
    cvShowImage("Out_test_第2幅", src4);
    cvShowImage("Out_Sun_test_第3幅", src6);
    cvWaitKey(0);
    //system("pause");
    cvReleaseHist(&hist_v[0]);
    cvReleaseHist(&hist_v[1]);
    cvReleaseHist(&hist_v[2]);
    cvReleaseHist(&hist_v[3]);
    cvReleaseHist(&hist_v[4]);
    cvReleaseHist(&hist_v[5]);  
    cvReleaseHist(&hist_h_s[0]);
    cvReleaseHist(&hist_h_s[1]);
    cvReleaseHist(&hist_h_s[2]);
    cvReleaseHist(&hist_h_s[3]);
    cvReleaseHist(&hist_h_s[4]);
    cvReleaseHist(&hist_h_s[5]);
    cvReleaseImage(&src1);
    cvReleaseImage(&src2);
    cvReleaseImage(&src3);
    cvReleaseImage(&src4);
    cvReleaseImage(&src5);
    cvReleaseImage(&src6);
    cvReleaseImage(&Imask);
    cvReleaseImage(&hsv1);
    cvReleaseImage(&hsv2);
    cvReleaseImage(&hsv3);
    cvReleaseImage(&hsv4);
    cvReleaseImage(&hsv5);
    cvReleaseImage(&hsv6);
    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);
    cvReleaseImage(&h_plane_4);
    cvReleaseImage(&s_plane_4);
    cvReleaseImage(&v_plane_4);
    cvReleaseImage(&h_plane_5);
    cvReleaseImage(&s_plane_5);
    cvReleaseImage(&v_plane_5);
    cvReleaseImage(&h_plane_6);
    cvReleaseImage(&s_plane_6);
    cvReleaseImage(&v_plane_6);
    cvDestroyAllWindows();
}