原理

总共有三个重点,
1、先将红色轮廓找出来
2、判断原图中某点在不在轮廓内部
3、进行遍历和填充

程序1:判断一个点是否在轮廓内的函数pointPolygonTest()的用法

OpenCV函数pointPolygonTest():

C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)

用于判断一个点是否在轮廓中

当measureDist设置为true时,若返回值为正,表示点在轮廓内部,返回值为负,表示在轮廓外部,返回值为0,表示在轮廓上。
当measureDist设置为false时,若返回值为+1,表示点在轮廓内部,返回值为-1,表示在轮廓外部,返回值为0,表示在轮廓上。
例:

/// 查找轮廓
std::vector<std::vector<cv::Point> > contours; 
cv::Mat src; //src为输入图像

cv::findContours( src, contours, CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0)); 

//判断p1(x,y)是否在轮廓内
cv::Point p1(x,y);
if (pointPolygonTest(Contours[j],cv::Point(x1,y1),false) == 1)
{
    cout<<p1<<"在轮廓内"<<endl;
}
……
程序2:检测红色,并将原图中红色转化为白色

找红色部分省略了,可以在我的博客里搜索:如何找红色物体
下面这部分主要是遍历图片,并判断点在不在轮廓内部,在内部时变化为白色


        //判断p1(x,y)是否在轮廓内

        int rowNumber = image_copy_C3.rows;//行数
        int colNumber = image_copy_C3.cols*image_copy_C3.channels();//列数
        for (int i = 0; i < rowNumber; i++)//行循环
        {
            uchar* data = image_copy_C3.ptr<uchar>(i);//获取第i行的首地址
            for (int j = 0; j < colNumber; j += 3)//列循环 彩色图像j+=3 灰度图像j++
            {

                if (pointPolygonTest(RectContours_2[0],Point(j, i), false) == 1)
                {
                    //cout << p1 << "在轮廓内" << endl;
                    data[j] = data[j + 1] = data[j + 2] = 255; //将轮廓内部变成白色
                }
            }
        }
效果图

检测红色,并将原图中红色转化为白色_将红色填充为白色