OpenCV 鼠标手动绘制掩码图像

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();

参考网站:
http://blog.csdn.net/wangyaninglm/article/details/41864021
http://answers.opencv.org/question/26415/cvzero-fucntion-for-c-api/

转载于:https://www.cnblogs.com/aobosir/p/5928666.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手动绘制mask屏蔽区域,然后对区域内的像素不进行检测,你可以按照以下步骤进行操作: 1. 创建一个空的mask矩阵,它应该与你的图像具有相同的尺寸和深度。 2. 使用OpenCV提供的函数(例如cv::rectangle,cv::circle等)在mask矩阵上绘制你想要屏蔽的区域,设置为白色(255)。 3. 对于不需要进行检测的区域,可以在mask矩阵中将它们设置为黑色(0)。 4. 将mask矩阵应用于你的图像,使用cv::bitwise_and函数将图像与mask相乘,这将把mask以外的像素设置为0。 5. 现在你可以在屏蔽区域中进行任何操作,例如将像素值设置为0或者将它们替换为其他值。 下面是一个简单的示例代码,它创建了一个屏蔽矩形并将其应用于图像: ```c++ // 读取图像 cv::Mat image = cv::imread("image.jpg"); // 创建一个空的mask矩阵 cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1); // 在mask上绘制一个矩形 cv::rectangle(mask, cv::Rect(100, 100, 200, 200), cv::Scalar(255), -1); // 在mask上绘制一个矩形并将其设置为黑色 cv::rectangle(mask, cv::Rect(150, 150, 100, 100), cv::Scalar(0), -1); // 应用mask到图像上 cv::Mat masked_image; cv::bitwise_and(image, mask, masked_image); // 在屏蔽区域中将像素设置为0 masked_image.setTo(cv::Scalar(0), mask); // 显示结果 cv::imshow("Masked Image", masked_image); cv::waitKey(0); ``` 在这个示例中,我们使用cv::rectangle函数在mask上绘制了一个矩形,并将其应用到了图像上。然后,我们使用cv::rectangle函数在mask上绘制了一个内部矩形,并将其设置为黑色。最后,我们使用cv::setTo函数将屏蔽区域内的像素设置为0。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值