ROI感兴趣区的提取方法
使用line,ellipse,ellipse,rectangle,fillPoly等函数绘制线、矩形、圆、椭圆等基本图形提取感兴趣区域
ROI感兴趣区的提取方法——鼠标操作提取方法
我们通过鼠标交互地提取ROI。OpenCV中鼠标操作依赖鼠标的回调函数和响应函数实现。主函数中调用鼠标的回调函数,将鼠标操作与程序的窗口绑定,产生鼠标操作时回调函数调用鼠标响应函数执行。
回调函数setMouseCallback
- void setMouseCallback( const string& winname,
- MouseCallback onMouse,
- void* userdata=0 )
Parameters:
第一个参数winname,windows视窗名称,对名为winname的视窗进行鼠标监控;
第二个参数onMouse,鼠标响应处理函数,监听鼠标的点击,移动,松开,判断鼠标的操作类型,并进行响应的函数处理;
第三个参数 userdata,鼠标响应处理函数的ID,与鼠标相应处理函数相匹配就行,暂时只用到默认为0的情况。
鼠标响应处理函数onMouse
OpenCV中,鼠标相应处理函数一般默认形参和返回参数。
void onMouse(int event,int x,int y,int flags,void *ustc)
Parameters:
第一个参数event,鼠标操作时间的整数代号,在opencv中,event鼠标事件总共有10中,从0-9依次代表如下:
- EVENT_MOUSEMOVE =0, //滑动
-
- EVENT_LBUTTONDOWN =1, //左键点击
-
- EVENT_RBUTTONDOWN =2, //右键点击
-
- EVENT_MBUTTONDOWN =3, //中间点击
-
- EVENT_LBUTTONUP =4, //左键释放
-
- EVENT_RBUTTONUP =5, //右键释放
-
- EVENT_MBUTTONUP =6, //中间释放
-
- EVENT_LBUTTONDBLCLK =7, //左键双击
-
- EVENT_RBUTTONDBLCLK =8, //右键双击
-
- EVENT_MBUTTONDBLCLK =9 //中间释放
第二个参数x,代表鼠标位于窗口的(x,y)坐标位置,窗口左上角默认为原点,向右为x轴,向下为y轴;
第三个参数y,代表鼠标的拖拽事件,以及键盘鼠标联合事件,总共有32种事件,这里不再赘述。
第四个参数flags,函数参数的编号。
=========================================================================
- #include"stdafx.h"
-
- #include
- #include
- #include
- #include
- using namespace cv;
- using namespace std;
-
- Point startp(-1, -1);
- Point endp(-1, -1);
- //绘制圆,需要中心坐标和半径
- Point centerp(-1, -1);
- int radius = 0;
- Mat temp;
- void MouseDraw(int event, int x, int y, int flag, void* usedata) {
- Mat image = *((Mat*)usedata);
- Mat roi;
- if (event == EVENT_LBUTTONDOWN) {//左键按下
- centerp.x = x;
- centerp.y = y;
- cout << "center point: " << centerp << endl;
- }
- else if (event == EVENT_MOUSEMOVE) {//鼠标移动
- if ((centerp.x > 0 )& (centerp.y > 0)) {
- //得有这个判断条件,不然一开始 不按下鼠标左键时就已经有起始点了
- endp.x = x;
- endp.y = y;
- int w = endp.x - centerp.x;
- int h = endp.y - centerp.y;
- radius = (int)sqrt(pow(w, 2) + pow(h, 2));
-
- temp.copyTo(image);
- //矩形可利用rectangle来实现
- circle(image, centerp, radius, Scalar(0, 0, 255), 2);
- namedWindow("mousedrawing", 0);
- resizeWindow("mousedrawing", 350, 350);
- imshow("mousedrawing", image);
- }
- }
- else if (event == EVENT_LBUTTONUP) {//左键抬起
- endp.x = x;
- endp.y = y;
- int w = endp.x - centerp.x;
- int h = endp.y - centerp.y;
- radius = (int)sqrt(pow(w, 2) + pow(h, 2));
-
- circle(image, centerp, radius, Scalar(0, 0, 255), 2);
- namedWindow("mousedrawing", 0);
- resizeWindow("mousedrawing", 350, 350);
- imshow("mousedrawing", image);
-
- //截取该部分图像
- //先截取矩形的部分,再用模取出圆形
- Rect rec;
- rec.x = centerp.x - radius;
- rec.y = centerp.y - radius;
- rec.width = 2 * radius;
- rec.height = 2 * radius;
- Mat Rec_roi = image(rec);//矩形的ROI区域
-
- Mat roi = Mat::zeros(Rec_roi.size(), Rec_roi.type());
- roi = Scalar(255, 255, 255);//将目标ROI背景置白
-
- //利用mask提取圆形的ROI
- Mat mask = Mat::zeros(Rec_roi.size(), Rec_roi.type());
- circle(mask, Point(radius, radius), radius, Scalar(255, 255, 255), -1);
- cvtColor(mask, mask, COLOR_BGR2GRAY);
- namedWindow("mask", 0);
- resizeWindow("mask", 350, 350);
- imshow("mask", mask);
-
- Rec_roi.copyTo(roi, mask);
- namedWindow("ROI", 0);
- resizeWindow("ROI", 350, 350);
- imshow("ROI", roi);
-
- //清空中心坐标,这样才会停止掉这一次的绘制
- centerp.x = -1;
- centerp.y = -1;
- }
- }
-
-
- int main(int argc, char*argv) {
- Mat image = imread("F:/photo/c.jpg",-1);
- namedWindow("mousedrawing",0);
- setMouseCallback("mousedrawing", MouseDraw, &image);
- resizeWindow("mousedrawing", 350, 350);
- imshow("mousedrawing", image);
-
- temp = image.clone();
-
- waitKey(0);
- destroyAllWindows();
- return 0;
- }
=========================================================================