openCV 感兴趣区域选择(鼠标事件)

通过鼠标选择感兴趣区域

小白,很多不懂的,有懂的前辈,烦请提醒我下哪些有问题。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

void on_mouse(int event, int x, int y, int flags, void* param);	//鼠标回调函数
void pointTrunc(Point& p);	//使点在图像区域内
int blind(Mat& src, Mat& dst); //输出图像盲元数
Mat g_srcImg, g_midImg, g_tmpImg, g_dstImg;

int main() {
	g_srcImg = imread("D:/CodeFile/sourceFiles/Image/test1.png", IMREAD_GRAYSCALE);
	if (!g_srcImg.data) {
		cout << "没有找到图像!" << endl;
		return 0;
	}
	namedWindow("img");
	imshow("img", g_srcImg);
	setMouseCallback("img", on_mouse);
	cout << "这是main函数,鼠标事件另外执行" << endl;
	waitKey(0);
	return 0;
}

void on_mouse(int event, int x, int y, int flags, void* param)
{
	static Point tlPoint(0, 0);	//矩形左上
	static Point curPoint(0, 0);  //当前鼠标点位置

	if (event == EVENT_LBUTTONDOWN) {
		tlPoint = Point(x, y);
		pointTrunc(tlPoint);
		cout << "矩形开始点:" << tlPoint << endl;
	}

	else if (event == EVENT_MOUSEMOVE && flags) {
		cvtColor(g_srcImg, g_tmpImg, COLOR_GRAY2BGR);	//为了彩色显示
		curPoint = Point(x, y);
		pointTrunc(curPoint);
		circle(g_tmpImg, curPoint, 4, Scalar(30, 100, 30), 2, 8);	//当前点位置突出显示
		rectangle(g_tmpImg, tlPoint, curPoint, Scalar(0, 255, 0));
		imshow("img", g_tmpImg);	//画的时候显示矩形框
	}
	else if (event == EVENT_LBUTTONUP) {
		cvtColor(g_srcImg, g_tmpImg, COLOR_GRAY2BGR);
		rectangle(g_tmpImg, tlPoint, curPoint, Scalar(0, 255, 0));
		imshow("img", g_tmpImg);	//画完显示矩形框
		int width = abs(tlPoint.x - curPoint.x);
		int height = abs(tlPoint.y - curPoint.y);
		if(width==0||height==0)
			cout << "未框选正确区域!" << endl;
		else {
			g_midImg = g_srcImg(Rect(min(curPoint.x, tlPoint.x), min(curPoint.y, tlPoint.y), width, height));	//选择ROI区域
			cout << "矩形结束点:" << curPoint << endl;
			imshow("midImg", g_midImg);
			int blindNums = blind(g_midImg, g_dstImg);
			cout << "盲元数目为:" << blindNums;
			imshow("dstImg", g_dstImg);
		}	
	}
}

void pointTrunc(Point& p)
{
	if (p.x < 0)
		p.x = 0;
	else if (p.x > g_srcImg.size().width)
		p.x = g_srcImg.size().width - 1;
	if (p.y < 0)
		p.y = 0;
	else if (p.y > g_srcImg.size().height)
		p.y = g_srcImg.size().height - 1;
}

int blind(Mat& src, Mat& dst) {
	if (src.type() != CV_8UC1) {
		cout << "错误:类型不是CV_8UC1的灰度图像";
		return -1;
	}

	//计算一帧的图像均值及方差
	Mat mat_mean, mat_stddev;
	meanStdDev(src, mat_mean, mat_stddev);
	double mean = mat_mean.at<double>(0, 0);
	double stddev = mat_stddev.at<double>(0, 0);
	unsigned char deltaTriple = 3 * stddev;
	int total = 0;

	//如果像素值大于3倍标准差则判断为盲元
	dst = Mat::zeros(src.size(), CV_8UC1);
	for (int i = 0; i < src.rows; ++i) {
		for (int j = 0; j < src.cols; ++j) {
			if (abs(src.at<uchar>(i, j) - mean) > deltaTriple) {
				dst.at<uchar>(i, j) = 255;
				++total;
			}
		}
	}
	return total;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值