#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
#define WINDOW_NAME "【程序窗口】" //为窗口标题定义的宏
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(cv::Mat& img);//画矩形函数
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345);
Point pt1,pt2;//pt1是鼠标按下起始点,pt2是末点
bool ready=false;
int main(int argc, char** argv)
{
Mat srcImage = imread("tennball.png");
resize(srcImage, srcImage,Size(600,500));
Mat img;
srcImage.copyTo(img);
Mat tempImage;
srcImage.copyTo(tempImage);
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
Mat hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
int hbins = 30, sbins = 32;
int histSize[] = { hbins, sbins };
float hranges[] = { 0, 180 };
float sranges[] = { 0, 256 };
const float* ranges[] = { hranges, sranges };
MatND hist;
int channels[] = { 0, 1 };
while (1)
{
srcImage.copyTo(tempImage);//拷贝源图到临时变量
if (g_bDrawingBox)
DrawRectangle(tempImage);
imshow(WINDOW_NAME, tempImage);
if (waitKey(1) == 27) break;//按下ESC键,程序退出
if (waitKey(1) == 'c')//按下c键,清除矩形
img.copyTo(srcImage);
if (ready) { // 处理生成反向投影
cout << "enter ready state \n";
Mat roi = hsv(Rect(pt1, pt2));
Mat roiHist;
calcHist(&roi, 1, channels, Mat(), roiHist, 2, histSize, ranges, true, false);
normalize(roiHist, roiHist, 0, 255, NORM_MINMAX, -1, Mat());
Mat backProjImg;
calcBackProject(&hsv, 1, channels, roiHist, backProjImg, ranges, 1, true);
imshow("backProj", backProjImg);
ready = false;
}
}
return 0;
}
void DrawRectangle(cv::Mat& img)
{
rectangle(img, Rect(pt1, pt2), cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)), 1);
}
//描述:鼠标回调函数,根据不同的鼠标事件进行不同的操作
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*) param;
switch (event)
{
//鼠标移动消息
case EVENT_MOUSEMOVE:
{
if (g_bDrawingBox)//如果是否进行绘制的标识符为真,记录
pt2 = Point(x, y);
}
break;
//左键按下消息
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
pt1 = Point(x, y);
pt2 = pt1;
}
break;
//左键抬起消息
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false;//置标识符为false
pt2= Point(x, y);
//调用函数进行绘制
DrawRectangle(image);
ready = true;
}
break;
}
}
效果图:鼠标拖动选择区域,对选择的区域进行反向投影