opencv多种方法区域选取Roi
1、鼠标选取
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat src, img1, mask, final;
Point point;
vector<Point> pts;
int drag = 0;
int var = 0;
int flag = 0;
void cv_show(string name, Mat img)
{
cv::namedWindow(name, 0);//CV_WINDOW_NORMAL就是0
resizeWindow(name, 1000, 1000); //创建一个500*500大小的窗口
cv::imshow(name, img);
waitKey(2);
}
void mouseHandler(int, int, int, int, void*);
void mouseHandler(int event, int x, int y, int, void*)
{
char temp[16];
// 左键按下
if (event == EVENT_LBUTTONDOWN && !drag)
{
if (flag == 0) // 标记是否生成掩码
{
// 第一次进入备份原图像
if (var == 0)
img1 = src.clone();
// 记录当前左键按下的点
point = Point(x, y);
// 在图像上将这个点用圆绘制出来,实心圆
circle(img1, point, 2, Scalar(0, 0, 255), -1, 8, 0);
// 点入vector
pts.push_back(point);
// 点的数量加1
var++;
// 表示已经有了一个点了
drag = 1;
sprintf_s(temp, "(%d,%d)", x, y);
putText(img1, temp, point, FONT_HERSHEY_SIMPLEX, 2, Scalar(255, 0,255),4,8);//只是实时显示鼠标移动的坐标
// 如果点的数量大于1,则绘制上一个点于当前点的直线
if (var > 1)
line(img1, pts[var - 2], point, Scalar(0, 0, 255), 2, 8, 0);
// 刷新图像
imshow("Source", img1);
cout << "img1大小:" << img1.size << endl;
}
}
// 左键松起
if (event == EVENT_LBUTTONUP && drag)
{
// 显示图像
imshow("Source", img1);
drag = 0;
}
// 右键按下
if (event == EVENT_RBUTTONDOWN)
{
// 表示右键
flag = 1;
// 备份图像
img1 = src.clone();
// 如果左键点击的得到的点数不为0,则绘制多边形
if (var != 0)
{
polylines(img1, pts, 1, Scalar(0, 0, 0), 2, 8, 0);
}
// 显示图像
imshow("Source", img1);
}
// 右键松起
if (event == EVENT_RBUTTONUP)
{
flag = var;
// 创建全为0的彩色图像
final = Mat::zeros(src.size(), CV_8UC1);
// 创建掩码图像
mask = Mat::zeros(src.size(), CV_8UC1);
vector<vector<Point> > vpts;
// 如果点集为孔,则什么都不做
if (pts.size() == 0)
{
return;
}
vpts.push_back(pts);
for (auto& array : vpts) {
for (auto& arr : array) {
std::cout << arr << ",";
}
std::cout << "\n";
}
// 用白色填充多边形(掩码图像)
fillPoly(mask, vpts, Scalar(255, 255, 255), 8, 0);
// 对原图像每一个像素进行与操作,使用mask掩码
bitwise_and(src, src, final, mask);
// 显示掩码图像
//imshow("Mask", mask);
cv_show("Mask", mask);
cout << "Mask大小:" << mask.size << endl;
// 显示结果图像
//imshow("Result", final);
cv_show("Result", final);
imwrite("result1.png", final);
cout << "final大小:" << final.size << endl;
// 显示原图像
imshow("Source", img1);
waitKey(0);
}
// 指示按下鼠标中间按钮,清除所有标记
if (event == EVENT_MBUTTONDOWN)
{
pts.clear();
var = 0;
drag = 0;
flag = 0;
imshow("Source", src);
}
}
int main(int argc, char** argv)
{
// 载入图像
src = imread("./Image_60.bmp");
//resize(src, src, Size(), 2.0, 2.0, INTER_LINEAR);
cout << "图像大小:"<<src.size << endl;
// 图像是否为孔
if (src.empty())
{
printf("Error open image !\n");
return 0;
}
// 创建窗口
namedWindow("Source", 0);
resizeWindow("Source", 500, 500); //创建一个500*500大小的窗口
// 调用鼠标回调函数
setMouseCallback("Source", mouseHandler, NULL);
// 显示图像
imshow("Source", src);
cout << "图像大小:" << src.size << endl;
waitKey(0);
return 0;
}
2、数组选取
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace cv;
using namespace std;
void cv_show(string name, Mat img)
{
cv::namedWindow(name, 0);//CV_WINDOW_NORMAL就是0
resizeWindow(name, 500, 500); //创建一个500*500大小的窗口
cv::imshow(name, img);
waitKey(2);
}
int main()
{
Mat src = imread("./Image_60.bmp");
cv_show("src", src);
Mat mask = Mat::zeros(src.size(), CV_8UC1);
Mat dst;
Mat bits;
vector<vector<Point2i>> contours;
vector<Point2i> points;
points.push_back(Point2i(100, 100));
points.push_back(Point2i(50, 150));
points.push_back(Point2i(1000, 2000));
points.push_back(Point2i(200, 200));
points.push_back(Point2i(220, 150));
points.push_back(Point2i(2000, 1000));
contours.push_back(points);
vector<vector<Point2i>> arrays{ {Point2i(685, 745),Point2i(2382, 755), Point2i(3069, 1738),Point2i(3070, 1988),Point2i(0, 1988),Point2i(3, 1744),Point2i(685, 745)} };
//vector<vector<Point2i>> arrays{ {Point2i(694, 753),Point2i(2379, 753), Point2i(3054, 1999),Point2i(18, 1978)} }; //[685, 745],[2382, 755],[3069, 1738],[3070, 1988],[0, 1988],[3, 1744],[685, 747]
//vector<vector<Point2i>> arrays{ {Point2i(694, 753),Point2i(2379, 753)}, {Point2i(3054, 1999),Point2i(18, 1978)} };
//std::vector<std::vector<Point>> arrays2{{(1,2),(6,5), {(2,2),(2,9)} }; //[694, 753],[2379, 753],[3054, 1999],[18, 1978]
for (auto& array : arrays) {
for (auto& arr : array) {
std::cout << arr << " ";
}
std::cout << "\n";
}
// 用白色填充多边形(掩码图像)
fillPoly(mask, arrays, Scalar(255, 255, 255), 8, 0);
// 对原图像每一个像素进行与操作,使用mask掩码
bitwise_and(src, src, bits, mask);
cv_show("bits", bits);
waitKey(0);
//drawContours(mask, contours, 0, Scalar::all(255), -1);
//imshow("src", src);
作用是把mask和src重叠以后把mask中像素值为0(black)的点对应的src中的点变为透明,而保留其他点。
//src.copyTo(dst, mask);
//imshow("dst", dst);
//waitKey(0);
return 0;
}
3、蒙窗选取(加法)
//对输入图片蒙窗,查看输出效果
cv::add(mask, img, img);
蒙窗制作:用画图软件,把要选取的部分填充成黑色,其他部分填充成白色