OpenCV第四章练习p126_3
参考:http://blog.csdn.net/xiajun07061225/article/details/6716496
运行结果:
以下是b题,程序运行后无法关闭,待研究:
#include <opencv/cv.h> #include <opencv/highgui.h> bool g_draw = false; bool g_draw_hist = false; CvRect g_box; // 画矩形 void draw_box(IplImage *image, CvRect rect, CvScalar scalar) { cvRectangle(image, cvPoint(rect.x, rect.y), cvPoint(rect.x+rect.width, rect.y+rect.height), scalar); cvShowImage("p126_3", image); } // 统计矩形蓝、绿、红像素数量,画直方图 void draw_hist(IplImage *image, CvRect rect) { cvSetImageROI(image, rect); IplImage *src = cvCreateImage( cvSize(rect.width, rect.height), IPL_DEPTH_8U, 3); cvCopy(image, src); cvResetImageROI(image); IplImage *r_img = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); IplImage *g_img = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); IplImage *b_img = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); // 分离B,G,R分量 cvSplit(src, b_img, g_img, r_img, NULL); int size = 256; float range[] = {0,255}; float *ranges[] = {range}; // 创建直方图 CvHistogram* r_hist = cvCreateHist(1, &size, CV_HIST_ARRAY, ranges, 1); CvHistogram* g_hist = cvCreateHist(1, &size, CV_HIST_ARRAY, ranges, 1); CvHistogram* b_hist = cvCreateHist(1, &size, CV_HIST_ARRAY, ranges, 1); // 红色分量 cvCalcHist(&r_img, r_hist, 0, NULL); IplImage *r_dst = cvCreateImage(cvSize(400,300), IPL_DEPTH_8U, 3); cvSet(r_dst, cvScalarAll(255), 0); float r_max = 0; cvGetMinMaxHistValue(r_hist, NULL, &r_max, NULL, NULL); double r_bin_width = (double)r_dst->width / size; double r_bin_unith = (double)r_dst->height / r_max;// 高度比例 for(int i = 0; i<size; i++){ // 获得矩阵左上角和右下角坐标 CvPoint p0 = cvPoint(i * r_bin_width, r_dst->height); CvPoint p1 = cvPoint((i + 1) * r_bin_width, r_dst->height - cvGetReal1D(r_hist->bins,i) * r_bin_unith); cvRectangle(r_dst, p0, p1, cvScalar(255,0,0), -1, 8, 0);// 画实心矩形 } cvNamedWindow("p126_3_r", CV_WINDOW_AUTOSIZE); cvShowImage("p126_3_r", r_dst); // 绿色分量 cvCalcHist(&g_img, g_hist, 0, NULL); IplImage *g_dst = cvCreateImage(cvSize(400,300), IPL_DEPTH_8U, 3); cvSet(g_dst, cvScalarAll(255), 0); float g_max = 0; cvGetMinMaxHistValue(g_hist, NULL, &g_max, NULL, NULL); double g_bin_width = (double)g_dst->width / size; double g_bin_unith = (double)g_dst->height / g_max;// 高度比例 for(int i = 0; i<size; i++){ // 获得矩阵左上角和右下角坐标 CvPoint p0 = cvPoint(i * g_bin_width, g_dst->height); CvPoint p1 = cvPoint((i + 1) * g_bin_width, g_dst->height - cvGetReal1D(g_hist->bins,i) * g_bin_unith); cvRectangle(g_dst, p0, p1, cvScalar(255,0,0), -1, 8, 0);// 画实心矩形 } cvNamedWindow("p126_3_g", CV_WINDOW_AUTOSIZE); cvShowImage("p126_3_g", g_dst); // 蓝色分量 cvCalcHist(&b_img, b_hist, 0, NULL); IplImage *b_dst = cvCreateImage(cvSize(400,300), IPL_DEPTH_8U, 3); cvSet(b_dst, cvScalarAll(255), 0); float b_max = 0; cvGetMinMaxHistValue(b_hist, NULL, &b_max, NULL, NULL); double b_bin_width = (double)b_dst->width / size; double b_bin_unith = (double)b_dst->height / b_max;// 高度比例 for(int i = 0; i<size; i++){ // 获得矩阵左上角和右下角坐标 CvPoint p0 = cvPoint(i * b_bin_width, b_dst->height); CvPoint p1 = cvPoint((i + 1) * b_bin_width, b_dst->height - cvGetReal1D(b_hist->bins,i) * b_bin_unith); cvRectangle(b_dst, p0, p1, cvScalar(255,0,0), -1, 8, 0);// 画实心矩形 } cvNamedWindow("p126_3_b", CV_WINDOW_AUTOSIZE); cvShowImage("p126_3_b", b_dst); cvWaitKey(0); cvDestroyWindow("p126_3_r"); cvDestroyWindow("p126_3_g"); cvDestroyWindow("p126_3_b"); } void my_mouse_callback(int event, int x, int y, int flags, void *param) { IplImage *temp = cvCloneImage((IplImage *)param);// 用局部变量保存副本,这样就不用显式释放 switch(event){ case CV_EVENT_LBUTTONDOWN: case CV_EVENT_RBUTTONDOWN:{ g_draw = true; g_box = cvRect(x, y, 0, 0); break; } case CV_EVENT_MOUSEMOVE:{ if(g_draw){ g_box.width = x - g_box.x; g_box.height = y - g_box.y; if(g_box.width<0){ g_box.x += g_box.width; g_box.width *= -1; } if(g_box.height<0){ g_box.y += g_box.height; g_box.height *= -1; } draw_box(temp, g_box, cvScalar(0x00,0x00,0xff)); } break; } case CV_EVENT_LBUTTONUP: case CV_EVENT_RBUTTONUP:{ g_draw = false; draw_box(temp, g_box, cvScalar(0xff,0x00,0x00)); draw_hist(temp, g_box); break; } default: g_draw = false; break; } } int main(int argc, char *argv[]) { char src[] = "F:\\test\\p126_3\\p126_3\\fruits.jpg"; IplImage *img = cvLoadImage(src, CV_LOAD_IMAGE_COLOR); if(!img){ cvNamedWindow("ERROR", CV_WINDOW_AUTOSIZE); cvWaitKey(0); return 0; } cvNamedWindow("p126_3", CV_WINDOW_AUTOSIZE); cvShowImage("p126_3", img); cvSetMouseCallback("p126_3", my_mouse_callback, (void *)img); while(1){ if(cvWaitKey(33) == 27) break; } cvReleaseImage(&img); cvDestroyWindow("p126_3"); return 1; }