#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\n", 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\n", x, y);
//printf("--->%d %d\n", 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\n", x, y);
//printf("--->%d %d\n", 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\n", 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\n", 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);
}