第七章 学习OpenCV(5)
运行结果如下图:
与上例一样,收集手的肤色直方图。以其中的一个室内直方图样本作为模型直方图匹配原理,并计算其与另一个室内直方图、一个室外阴影直方图、一个室外光照直方图的EMD距离,利用这些测量值设置一个距离阈值,再次比较EMD距离,程序中三幅图像已经过处理,依次比前一幅亮度增加25,具体代码如下:
#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, *src4, *Imask, *hsv1, *hsv2, *hsv3, *hsv4; //源图像 HSV格式图像
//src1 src2 src3 每张亮度较前一张增加了10 src3 src4增加40
//模板
if (!(src1 = cvLoadImage("D:\\Template\\OpenCV\\Template53_hue-saturation_Compare_EMD\\Debug\\handdd.jpg")))
return -1;
//室内
if (!(src2 = cvLoadImage("D:\\Template\\OpenCV\\Template53_hue-saturation_Compare_EMD\\Debug\\handd.jpg")))
return -2;
//室外阴影
if (!(src3 = cvLoadImage("D:\\Template\\OpenCV\\Template53_hue-saturation_Compare_EMD\\Debug\\handdd_out.jpg")))
return -3;
//室外光照
if (!(src4 = cvLoadImage("D:\\Template\\OpenCV\\Template53_hue-saturation_Compare_EMD\\Debug\\handdd_out_sun.jpg")))
return -4;
//Mask为手掌掩码 过滤掉其他背景 只分析手掌颜色直方图 可略
if (!(Imask = cvLoadImage("D:\\Template\\OpenCV\\Template53_hue-saturation_Compare_EMD\\Debug\\Imask1.jpg",
CV_LOAD_IMAGE_GRAYSCALE)))
return -5;
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);
cvCvtColor(src1, hsv1, CV_BGR2HSV); //源图像->HSV格式图像
cvCvtColor(src2, hsv2, CV_BGR2HSV); //源图像->HSV格式图像
cvCvtColor(src3, hsv3, CV_BGR2HSV); //源图像->HSV格式图像
cvCvtColor(src4, hsv4, 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 *planes1[] = { h_plane_1, s_plane_1 }; //色相饱和度数组
IplImage *planes2[] = { h_plane_2, s_plane_2 }; //色相饱和度数组
IplImage *planes3[] = { h_plane_3, s_plane_3 }; //色相饱和度数组
IplImage *planes4[] = { h_plane_4, s_plane_4 }; //色相饱和度数组
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); //图像分割
//cvSplit(hsv, h_plane, s_plane, v_plane, NULL);
//建立直方图
CvHistogram *hist1, *hist2, *hist3, *hist4;
int h_bins = 30, s_bins = 32;
int hist_size[] = { h_bins, s_bins }; //对应维数包含bins个数的数组
float h_ranges[] = { 0, 180 }; //H通道划分范围 饱和度0-180
float s_ranges[] = { 0, 255 }; //S通道划分范围
float* ranges[] = { h_ranges, s_ranges }; //划分范围数对, ****均匀bin,range只要最大最小边界
//创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图)
hist1 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
hist2 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
hist3 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
hist4 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
//创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图)
cvCalcHist(planes1, hist1, 0, Imask); //计算直方图(图像,直方图结构,不累加,mask仅采集手掌)
cvCalcHist(planes2, hist2, 0, 0); //计算直方图(图像,直方图结构,不累加,掩码)
cvCalcHist(planes3, hist3, 0, 0); //计算直方图(图像,直方图结构,不累加,掩码)
cvCalcHist(planes4, hist4, 0, 0); //计算直方图(图像,直方图结构,不累加,掩码)
//cvNormalizeHist(hist1, 1.0); //直方图归一化
//cvNormalizeHist(hist2, 1.0); // 归一化不可在此调用,后面要调用阈值化
//cvNormalizeHist(hist3, 1.0);
//cvNormalizeHist(hist4, 1.0);
CvMat *sig1, *sig2, *sig3, *sig4;
int numrows = h_bins*s_bins;
sig1 = cvCreateMat(numrows, 3, CV_32FC1); //numrows行 3列 矩阵
sig2 = cvCreateMat(numrows, 3, CV_32FC1);
sig3 = cvCreateMat(numrows, 3, CV_32FC1); //numrows行 3列 矩阵
sig4 = cvCreateMat(numrows, 3, CV_32FC1);
for (int i = 0; i < 2; i++)
{
for (int h = 0; h < h_bins; h++)
{
for (int s = 0; s < s_bins; s++)
{
double bin_val = cvQueryHistValue_2D(hist1, h, s);
//h:行数 s_bins:总列数(行长度)s:列数 h*s_bins+s 当前bin对应的sig行数
cvSet2D(sig1, h*s_bins + s, 0, cvScalar(bin_val));
cvSet2D(sig1, h*s_bins + s, 1, cvScalar(h));
cvSet2D(sig1, h*s_bins + s, 2, cvScalar(s));
bin_val = cvQueryHistValue_2D(hist2, h, s);
cvSet2D(sig2, h*s_bins + s, 0, cvScalar(bin_val));
cvSet2D(sig2, h*s_bins + s, 1, cvScalar(h));
cvSet2D(sig2, h*s_bins + s, 2, cvScalar(s));
bin_val = cvQueryHistValue_2D(hist3, h, s);
cvSet2D(sig3, h*s_bins + s, 0, cvScalar(bin_val));
cvSet2D(sig3, h*s_bins + s, 1, cvScalar(h));
cvSet2D(sig3, h*s_bins + s, 2, cvScalar(s));
bin_val = cvQueryHistValue_2D(hist4, h, s);
cvSet2D(sig4, h*s_bins + s, 0, cvScalar(bin_val));
cvSet2D(sig4, h*s_bins + s, 1, cvScalar(h));
cvSet2D(sig4, h*s_bins + s, 2, cvScalar(s));
}
}
float emd1 = cvCalcEMD2(sig1, sig2, CV_DIST_L2);
float emd2 = cvCalcEMD2(sig1, sig3, CV_DIST_L2);
float emd3 = cvCalcEMD2(sig1, sig4, CV_DIST_L2);
std::printf("Room EMD: %f; \n", emd1);
std::printf("Outside EMD: %f; \n", emd2);
std::printf("Outside_sun EMD: %f; \n", emd3);
cvThreshHist(hist2, 87); //距离阈值描述不明确,threshhold:87 EMD最小
cvThreshHist(hist3, 87);
cvThreshHist(hist4, 87);
if (i==0)
cout << endl << endl << "After Threshhold" << endl << endl;
}
cvNamedWindow("Model", 1);
cvNamedWindow("Room", 1);
cvNamedWindow("Outside", 1);
cvNamedWindow("Outside_sun", 1);
cvNamedWindow("IMASK", 1);
cvShowImage("Model", src1);
cvShowImage("Room", src2);
cvShowImage("Outside", src3);
cvShowImage("Outside_sun", src4);
cvShowImage("IMASK", Imask);
cvWaitKey(0);
cvReleaseMat(&sig1);
cvReleaseMat(&sig2);
cvReleaseMat(&sig3);
cvReleaseMat(&sig4);
cvReleaseHist(&hist1);
cvReleaseHist(&hist2);
cvReleaseHist(&hist3);
cvReleaseHist(&hist4);
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();
}
http://www.jiaoanw.com/%E6%95%99%E6%A1%88%E6%A0%BC%E5%BC%8F/article-43870-5.html
http://www.jiaoanw.com/
true
教案网
http://www.jiaoanw.com/%E6%95%99%E6%A1%88%E6%A0%BC%E5%BC%8F/article-43870-5.html
report
14524
运行结果如下图: 与上例一样,收集手的肤色直方图。以其中的一个室内直方图样本作为模型 直方图匹配原理 ,并计算其与另一个室内直方图、一个室外
马总