如何在OpenCV中将圆形外的所有内容变为黑色

6

我目前正在尝试将圆形外的所有内容渲染为黑色。 我使用以下代码绘制圆形:

cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); // CVRound converts floating numbers to integer
int radius = cvRound(circles[i][2]);                              // Radius is the third parameter [i][0] = x [i][1]= y [i][2] = radius
circle( image, center, 3, cv::Scalar(0,255,0), -1, 8, 0 );        // Drawing little circle to Image Center , next Line of Code draws the real circle
circle( image, center, radius, cv::Scalar(0,0,255), 3, 8, 0 );    // Circle(img, center, radius, color, thickness=1, lineType=8, shift=0)

如果我有一个圆的半径和中心点,想要将整个圆涂成黑色,最好的方法是什么?OpenCV是否提供了方便的机制来完成此操作,还是应该迭代图像的所有像素,根据位置将其涂成黑色或不涂?

6
创建一个掩膜图像(在与原始图像大小相同的黑色图像上用白色画圆),然后使用 bitwise_and() 函数将其与原图像进行按位与运算。 - Abid Rahman K
4个回答

7
感谢Abid提供的提示,我最终采用了这种方法。一切顺利:
cv::Mat src = someMethodThatReturnsSrcImage(); // src Image 
cv::Mat maskedImage; // stores masked Image
std::vector<cv::Vec3f> circles = someMethodThatReturnsCircles(src);    
cv::Mat mask(srcImageForDimensions.size(),srcImageForDimensions.type());  // create an Mat that has same Dimensons as src
mask.setTo(cv::Scalar(0,0,0));                                            // creates black-Image
    // Add all found circles to mask
for( size_t i = 0; i < circles.size(); i++ )                          // iterate through all detected Circles
       {
         cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); // CVRound converts floating numbers to integer
         int radius = cvRound(circles[i][2]);                              // Radius is the third parameter [i][0] = x [i][1]= y [i][2] = radius
         cv::circle( mask, center, radius, cv::Scalar(255,255,255),-1, 8, 0 );    // Circle(img, center, radius, color, thickness=1, lineType=8, shift=0)
       }

src.copyTo(maskedImage,mask); // creates masked Image and copies it to maskedImage

3

您可以将背景颜色设为任意颜色。

image=cv::Scalar(red_value, green_value, blue_value);

然后画出你的圆形。

1

我认为你问题下面的那个评论是最佳解决方案。 我修改了你的代码,用于来自鱼眼相机的5M图像。这张图片还需要将圆外的所有点变成黑色。

#include <Windows.h>
#include <Vfw.h>
#include <string>
#include <iostream>    
#include "opencv2\core\core.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\imgcodecs\imgcodecs.hpp"
#include "opencv2\highgui\highgui.hpp"    
using namespace std;
using namespace cv;    
int _tmain(int argc, _TCHAR* argv[])
{
    cv::Mat im_source_non_square = cv::imread("D:/FishLib/sample_02.bmp", CV_LOAD_IMAGE_COLOR);
    cv::namedWindow("Image",CV_WINDOW_FREERATIO);
    cv::imshow("Image", im_source_non_square);
    Mat im_source_square;
    int m_nCenterX=1280;
    int m_nCenterY=960;
    int m_nRadius=916;
    Mat im_mask=im_source_non_square.clone();
    im_mask.setTo(cv::Scalar(0,0,0));
    circle( im_mask, cv::Point(m_nCenterX,m_nCenterY), m_nRadius, cv::Scalar(255,255,255), -3, 8, 0 );
    cv::namedWindow("Mask image",CV_WINDOW_FREERATIO);
    cv::imshow("Mask image", im_mask);
    Mat im_source_circle;
    cv::bitwise_and(im_source_non_square,im_mask,im_source_circle);
    cv::namedWindow("Combined image",CV_WINDOW_FREERATIO);
    cv::imshow("Combined image", im_source_circle);
    cv::waitKey(0);
    return 0;
}

0
刚试了一下你的代码片段,它可以正常工作。 如果你想更改背景颜色而不是黑色,根据 opencv 文档 这里, 在 copyTo 之前,目标 mat 如果需要将被初始化,所以只需添加以下代码:
cv::Mat maskedImage(srcImageForDimensions.size(), srcImageForDimensions.type()); // stores masked Image 
maskedImage.setTo(cv::Scalar(0,0,255)); // set background color to red

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接