通过鼠标选择感兴趣区域
小白,很多不懂的,有懂的前辈,烦请提醒我下哪些有问题。
#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;
}