您的位置:首页 > 运维架构

OpenCV 鼠标手动绘制掩码图像

2016-07-04 03:54 369 查看

OpenCV 鼠标手动绘制掩码图像

完整的代码:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
using namespace cv;

cv::Mat  marker_mask;
cv::Mat markers;
cv::Mat img0, img, img_gray, wshed;
cv::Point prev_pt(-1,-1);

void on_mouse( int event, int x, int y, int flags, void* param )
{
if( !img.data )
return;

if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
prev_pt = cv::Point(-1,-1);
else if( event == CV_EVENT_LBUTTONDOWN )
prev_pt = cv::Point(x,y);
else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
{
cv::Point pt(x,y);
if( prev_pt.x < 0 )
prev_pt = pt;
cv::line( marker_mask, prev_pt, pt, cv::Scalar::all(255), 1, 8, 0 );
cv::line( img, prev_pt, pt, cv::Scalar::all(255), 1, 8, 0 );
prev_pt = pt;
cv::imshow( "image", img );
}
}

int main(){
img0 = cv::imread("phase_map_org.bmp", 1);
if(!img0.data)
return 0;

cv::namedWindow( "image" );
cv::namedWindow( "watershed transform" );

img = img0.clone();
img_gray = img0.clone();
wshed = img0.clone();
marker_mask = cv::Mat( img.size(), CV_8U, cv::Scalar::all(0));

cv::imshow( "image", img );
cv::imshow( "watershed transform", wshed );
cvSetMouseCallback( "image", on_mouse, 0 );

for(;;){
int c = cv::waitKey(0);

if( (char)c == 27 )
break;

if( (char)c == 'r' )  {
marker_mask.setTo(cv::Scalar::all(0));
img0.copyTo(img);
cv::imshow( "image", img );
}
if( (char)c == 's' )  {
cv::imwrite("marker_mask.bmp", marker_mask);
std::cout << "save marker_mask.bmp finals " << std::endl;
}
if( (char)c == 'p' )  {
std::cout << "processing ... " << std::endl;
std::vector<std::vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
cv::findContours( marker_mask, contours,
CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );

marker_mask.setTo(cv::Scalar::all(0));
cv::drawContours( marker_mask, contours, -1,
cv::Scalar(255), CV_FILLED );

//cv::Mat color_tab;
std::cout << contours.size() << std::endl;

cv::imshow( "image", marker_mask );
}
}

cv::waitKey(0);
return 0;
}

得到掩码图像

将闭合环线外的部分像素值全设为0,内部全设为255.
就是在for(;;)循环里面的:

if( (char)c == 'p' )  {
std::cout << "processing ... " << std::endl;
std::vector<std::vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
cv::findContours( marker_mask, contours,
CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );

marker_mask.setTo(cv::Scalar::all(0));
cv::drawContours( marker_mask, contours, -1,
cv::Scalar(255), CV_FILLED );

//cv::Mat color_tab;
std::cout << contours.size() << std::endl;

cv::imshow( "image", marker_mask );
}

运行程序:鼠标手动绘制一个闭合环线,按P生成掩码图像

知识点

  1. 清零函数
    OpenCV1的函数

    cvZero( marker_mask );

    等同于OpenCV2的函数:

    marker_mask.setTo(cv::Scalar::all(0));
  2. 复制函数和克隆函数
    OpenCV1的函数

    cvCopy( 原图, 副本);

    等同于OpenCV2的函数:

    原图.copyTo(副本);

    或着

    副本 = 原图.clone();

参考网站:
https://www.geek-share.com/detail/2629267463.html
http://answers.opencv.org/question/26415/cvzero-fucntion-for-c-api/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: