前言
1.在圖像進行中,會用滑鼠選擇一個感興趣的區域進行相關的操作,我這裡示範如何用滑鼠選擇任何形狀的ROI,就你Ps的摳圖一樣,使用滑鼠左鍵選擇一個任何形狀的區域,生成新的圖像。
2.我示範的代碼環境是,IDE是VS2015,使用的是OpenCV3.30這個版本。
選擇任何形狀的ROI
#include <iostream>
#include<opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
//定義全局坐标系
Point prev_pt = Point(-1, -1);
Mat src, background_img, foreground_img;
void on_mouse(int event, int x, int y, int flags, void*)
{
//松開滑鼠左鍵或不是按住左鍵拖拽的動作時,把坐标還原
if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))
{
prev_pt = Point(-1, -1);
}
//按下左鍵
else if (event == CV_EVENT_LBUTTONDOWN)
{
prev_pt = Point(x, y);
}
//移動滑鼠并按住左鍵拖拽
else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
{
Point pt = Point(x, y);
//前景模闆上劃線
line(foreground_img, prev_pt, pt, Scalar(255), 2, 8, 0);
//原圖上劃線 Scalar::all(255)意思就是BGR通道像素值全為255
line(src, prev_pt, pt, Scalar::all(255), 2, 8, 0);
//起點等于終點,說明曲線要比
prev_pt = pt;
imshow("原圖", src);
}
//點選右鍵,截取所選區域
if (event == CV_EVENT_RBUTTONUP)
{
Mat dst;
//畫線閉合區域被白色填充顯示在原始圖像上
floodFill(foreground_img, Point(x, y), Scalar(255));
// img中被FG_mask掩蓋後的圖像附到FG中顯示
src.copyTo(dst, foreground_img);
namedWindow("ROI", 0);
imshow("ROI", dst);
}
}
int main()
{
Mat image = imread("4.jpg");
//初始化前景和背景模闆
foreground_img = Mat(image.size(), CV_8UC1, Scalar(0));
image.copyTo(src);
//顯示原圖
namedWindow("原圖", 0);
imshow("原圖", src);
cvSetMouseCallback("原圖", on_mouse, 0);
waitKey(0);
return 0;
}
結果
1.運作之後,按下滑鼠左鍵,對着要選擇的區域拖動滑鼠描邊,閉合之後松開左鍵,點選右鍵,得到ROI區域。
2.如果不閉合,按漫水填充的算法,會得到整張圖像。