#include <cv.h> #include <highgui.h> IplImage* img; void mouse_set(int event, int x, int y, int flags, void* param); void addHigh(IplImage *image, CvRect rectangle); void draw_grap(IplImage* image, CvRect rectangle); int main() { img = cvLoadImage("3.jpg", 1); cvNamedWindow("main", 1); cvSetMouseCallback("main", mouse_set, 0); cvShowImage("main", img); cvWaitKey(0); //cvReleaseImage(&img); //cvDestroyAllWindows(); } void mouse_set(int event, int x, int y, int flags, void* param) { IplImage* image = cvCloneImage(img); IplImage* src = cvCloneImage(img); IplImage* des = cvCloneImage(img); IplImage* finn = 0; static CvPoint src_point = { -1, -1 }; static CvPoint des_point = { -1, -1 }; if (event == CV_EVENT_LBUTTONDOWN) { cvCopy(image, src); printf("%d %d ", x, y); cvShowImage("main", src); src_point = cvPoint(x, y); cvCopy(des, src); } else if (event == CV_EVENT_MOUSEMOVE &&!(flags & CV_EVENT_FLAG_LBUTTON)) { cvCopy(des, src); //printf("%d %d ", x, y); //printf("--->%d %d ", src_point.x, src_point.y); des_point = cvPoint(x, y); cvCopy(src, des); } else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON)) { cvCopy(des, src); //printf("%d %d ", x, y); //printf("--->%d %d ", src_point.x, src_point.y); des_point = cvPoint(x, y); cvRectangle(src, src_point, des_point, cvScalar(0xff, 0, 0), 1, 8, 0); cvShowImage("main", src); } else if (event == CV_EVENT_LBUTTONUP) { cvCopy(des, src); //printf("%d %d ", x, y); des_point = cvPoint(x, y); cvShowImage("main", src); cvCopy(src, des); CvRect rectangle; cvRectangle(src, src_point, des_point, cvScalar(0, 255, 0), 1, 8, 0); int width = abs(des_point.x - src_point.x); int height = abs(des_point.y - src_point.y); rectangle = cvRect(src_point.x, src_point.y, width, height); printf("src_point.x = %d src_point.y = %d , des_point.x = %d des_point.y = %d ", src_point.x, src_point.y, des_point.x, des_point.y); finn = cvCreateImage(cvSize(width, height), img->depth, img->nChannels); if (rectangle.width < 0) { rectangle.x += rectangle.width; rectangle.width *= -1; } if (rectangle.height < 0) { rectangle.y += rectangle.height; rectangle.height *= -1; } addHigh(image, rectangle); draw_grap(image, rectangle); } } void addHigh(IplImage *image, CvRect rectangle) { for (int row = rectangle.y; row < rectangle.height + rectangle.y; row++) { //uchar *ptr = (uchar*)(image->imageData + row*image->widthStep); uchar *ptr = (uchar*)(image->imageData + row * image->widthStep); for (int col = rectangle.x; col < rectangle.x + rectangle.width; col++) { ptr[(col * 3 + 1)] = 10; ptr[(col * 3 + 2)] = 10;// } if (row >= image->height - 1) { row = image->height; } } } void draw_grap(IplImage* image, CvRect rectangle) { if (rectangle.x <= 0 || rectangle.y <= 0 || rectangle.height <= 0 || rectangle.width <= 0) { return; } cvSetImageROI(image, rectangle); IplImage* B_img1 = cvCreateImage(cvGetSize(image), 8, 3); IplImage* B_img2 = cvCreateImage(cvGetSize(image), 8, 1); IplImage* S_img1 = cvCreateImage(cvSize(rectangle.width, rectangle.height), 8, 1); IplImage* S_img2 = cvCreateImage(cvSize(rectangle.width, rectangle.height), 8, 1); IplImage* planes[] = { B_img2, S_img1 }; int b_bins = 16, s_bins = 8; int hist_size[] = { b_bins, s_bins }; float h_ranges[] = { 0, 180 }; float s_ranges[] = { 0, 255 }; float*ranges[] = { h_ranges, s_ranges }; cvCvtColor(image, B_img1, CV_BGR2HSV); //颜色空间转换函数 对image图像转换成HSV H->色调 S->饱和度 V->亮度 cvResetImageROI(image); cvCvtPixToPlane(B_img1, B_img2, S_img1, S_img2, 0); //分割一个多通道图像成多个单通道图像 或者只提取一个通道 CvHistogram * hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1); //创建直方图 cvCalcHist(planes, hist, 0, 0); //用来计算图像直方图 /* 第一个参数 需要计算直方图的图形 第二个参数 直方图的指针 第三个参数累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。 第四个参数操作 mask, 确定输入图像的哪个象素被计数 */ float max_value; cvGetMinMaxHistValue(hist, 0, &max_value, 0, 0); //缩放最大值和最小值 int height = 480; int width = (b_bins*s_bins * 6); IplImage* hist_img = cvCreateImage(cvSize(width, height), 8, 3); cvZero(hist_img); IplImage * hsv_color = cvCreateImage(cvSize(1, 1), 8, 3); IplImage * rgb_color = cvCreateImage(cvSize(1, 1), 8, 3); int bin_w = width / (b_bins * s_bins); for (int h = 0; h < b_bins; h++) { for (int s = 0; s < s_bins; s++) { int i = h*s_bins + s; float bin_val = cvQueryHistValue_2D(hist, h, s); //获取当前坐标的颜色 int intensity = cvRound(bin_val*height / max_value); //四舍五入 cvSet2D(hsv_color, 0, 0, cvScalar(h*180.f / b_bins, s*255.f / s_bins, 255, 0)); cvCvtColor(hsv_color, rgb_color, CV_HSV2BGR); CvScalar color = cvGet2D(rgb_color, 0, 0); cvRectangle(hist_img, cvPoint(i*bin_w, height), cvPoint((i + 1)*bin_w, height - intensity), color, -1, 8, 0); } } cvNamedWindow("show", 1); cvShowImage("show", hist_img); }