OPENCV实例:鼠标选择区域进行反向投影

 

#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;
	}
}


效果图:鼠标拖动选择区域,对选择的区域进行反向投影

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想想叫啥名

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值