Search code examples
c#opencvcontouremgucv

Emgu.DrawContours() can not fill region


I want to fill regions by setting thickness to -1.Result is Unbelievable:the second contour is filled ,but the first is not filled.

source

result

var result= new Image<Bgr, byte>(source.Width, source.Height);
result.SetValue(new Bgr(255,255,255));

VectorOfVectorOfPoint contours =new VectorOfVectorOfPoint();
var temp = source.Canny(128, 255);
CvInvoke.FindContours(temp , contours,null, RetrType.External,ChainApproxMethod.ChainApproxSimple);

CvInvoke.DrawContours(result, contours, 1, new MCvScalar(0,255,0),-1);
CvInvoke.DrawContours(result, contours, 0, new MCvScalar(0,255, 0), -1);

result =result.GetSubRect(getMaxRectangle(contours))

I tried to use different LineType but failed, especially LineType.Filled cause a error :OpenCV: connectivity == 8 || connectivity == 4. I want to know why it happened.


Solution

  • I'll just write the code in python, if it will help you:

    gray = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY) # convert to gray
    _, threshold = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY_INV) # inverse thresholding
    contours, _ = cv2.findContours(threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # find contours
    imContoured = cv2.drawContours(im.copy(), contours, 0, (0,0,255), -1) # fill it blue (in cv it will be red)
    imContoured = cv2.drawContours(imContoured, contours, 1, (0,255,0), -1) # fill it green
    

    And here is the result:

    Result

    So basically no need to do Canny edge detection, your image is good to go with some threshold (remember to use cv2.THRESH_BINARY_INV)

    Okay so I guess maybe for you, this will be something like this:

    Mat gray = new Mat();
    CvInvoke.CvtColor(source, gray, ColorConversion.Bgr2Gray);
    // Inverse thresholding
    Mat threshold = new Mat();
    CvInvoke.Threshold(gray, threshold, 250, 255, ThresholdType.BinaryInv);
    // Find contours
    VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
    CvInvoke.FindContours(threshold, contours, null, RetrType.External, ChainApproxMethod.None);
    

    The drawing would not change anything, it is correct. I guess with canny detection something went wrong, can't say what exactly, but maybe the contour was broken or something. To make sure, can you please show us how your canny edges looked like?