Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Could not perform 'fill' using draw contours

Code and Result

cv::Mat img, output;
UIImageToMat(input, img, false);

cv::Mat grayed;
cv::cvtColor(img, grayed, COLOR_BGR2GRAY);
cv::GaussianBlur(grayed, grayed, cv::Size(7, 7), 2);

int erosion_size = 1;
cv::Mat element = cv::getStructuringElement(0, cv::Size(erosion_size + 1, erosion_size + 1), cv::Point(1, 1));
cv::Mat temp;

cv::morphologyEx(grayed, temp, MORPH_GRADIENT, element);
cv::Mat dilateKernel(cv::Size(7, 7), CV_8UC1, cv::Scalar(1));
cv::dilate(temp, temp, dilateKernel);
cv::bitwise_not(temp, temp);
adaptiveThreshold(~temp, temp, 255, ADAPTIVE_THRESH_MEAN_C, 0, 207, -2);

    //skel
cv::Mat skel(grayed.size(), CV_8UC1, cv::Scalar(0));
cv::Mat temp1(grayed.size(), CV_8UC1);
cv::Mat element1 = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
bool done;
do {
    cv::morphologyEx(temp, temp1, cv::MORPH_OPEN, element1);
    cv::bitwise_not(temp1, temp1);
    cv::bitwise_and(temp, temp1, temp1);
    cv::bitwise_or(skel, temp1, skel);
    cv::erode(temp, temp, element1);

    double max;
    cv::minMaxLoc(temp, 0, &max);
    done = (max == 0);

} while (!done);

    //contour
vector<vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
findContours( skel, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

Mat drawing = Mat::zeros( skel.size(), CV_8UC3 );

for( int i = 0; i< contours.size(); i++ ) {

    std::vector<cv::Point> contour_line;
    cv::approxPolyDP(cv::Mat(contours[i]), contour_line, 5, true);
    int nc = (int)contour_line.size();
    const cv::Point * pc = &(contour_line[0]);
    cv::polylines( drawing, &pc, &nc, 1, 0, cv::Scalar(255, 255, 255), nc, FILLED);
    drawContours(drawing, contours, i, Scalar(200, 200, 0), FILLED);
}
return MatToUIImage(drawing);

Question

I have followed this tutorial for Morphological Skeleton. The input and the skeleton result are here.

After performing morphological Skeleton operation, I'm processing findContours and filling it with drawContours. However the end result is not as expected. It thickens the border of each letter instead of filling. Could anyone advice what am I missing? Or do I need to perform any other operation instead of drawContours?

Note: This is most likely a follow-up question of my previous one.

Could not perform 'fill' using draw contours

Code and ResultComplete Code

cv::Mat img, output;
UIImageToMat(input, img, false);

cv::Mat grayed;
cv::cvtColor(img, grayed, COLOR_BGR2GRAY);
cv::GaussianBlur(grayed, grayed, cv::Size(7, 7), 2);

int erosion_size = 1;
cv::Mat element = cv::getStructuringElement(0, cv::Size(erosion_size + 1, erosion_size + 1), cv::Point(1, 1));
cv::Mat temp;

cv::morphologyEx(grayed, temp, MORPH_GRADIENT, element);
cv::Mat dilateKernel(cv::Size(7, 7), CV_8UC1, cv::Scalar(1));
cv::dilate(temp, temp, dilateKernel);
cv::bitwise_not(temp, temp);
adaptiveThreshold(~temp, temp, 255, ADAPTIVE_THRESH_MEAN_C, 0, 207, -2);

    //skel
cv::Mat skel(grayed.size(), CV_8UC1, cv::Scalar(0));
cv::Mat temp1(grayed.size(), CV_8UC1);
cv::Mat element1 = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
bool done;
do {
    cv::morphologyEx(temp, temp1, cv::MORPH_OPEN, element1);
    cv::bitwise_not(temp1, temp1);
    cv::bitwise_and(temp, temp1, temp1);
    cv::bitwise_or(skel, temp1, skel);
    cv::erode(temp, temp, element1);

    double max;
    cv::minMaxLoc(temp, 0, &max);
    done = (max == 0);

} while (!done);

    //contour
vector<vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
findContours( skel, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

Mat drawing = Mat::zeros( skel.size(), CV_8UC3 );

for( int i = 0; i< contours.size(); i++ ) {

    std::vector<cv::Point> contour_line;
    cv::approxPolyDP(cv::Mat(contours[i]), contour_line, 5, true);
    int nc = (int)contour_line.size();
    const cv::Point * pc = &(contour_line[0]);
    cv::polylines( drawing, &pc, &nc, 1, 0, cv::Scalar(255, 255, 255), nc, FILLED);
    drawContours(drawing, contours, i, Scalar(200, 200, 0), FILLED);
}
return MatToUIImage(drawing);

Question

I have followed this tutorial for Morphological Skeleton. The input and the skeleton result are here.

After performing morphological Skeleton operation, I'm processing findContours and filling it with drawContours. However the end result is not as expected. It thickens the border of each letter instead of filling. Could anyone advice what am I missing? Or do I need to perform any other operation instead of drawContours?

Note: This is most likely a follow-up question of my previous one.

Could not perform 'fill' using draw contours

Complete Code

cv::Mat img, output;
UIImageToMat(input, img, false);

cv::Mat grayed;
cv::cvtColor(img, grayed, COLOR_BGR2GRAY);
cv::GaussianBlur(grayed, grayed, cv::Size(7, 7), 2);

int erosion_size = 1;
cv::Mat element = cv::getStructuringElement(0, cv::Size(erosion_size + 1, erosion_size + 1), cv::Point(1, 1));
cv::Mat temp;

cv::morphologyEx(grayed, temp, MORPH_GRADIENT, element);
cv::Mat dilateKernel(cv::Size(7, 7), CV_8UC1, cv::Scalar(1));
cv::dilate(temp, temp, dilateKernel);
cv::bitwise_not(temp, temp);
adaptiveThreshold(~temp, temp, 255, ADAPTIVE_THRESH_MEAN_C, 0, 207, -2);

    //skel
cv::Mat skel(grayed.size(), CV_8UC1, cv::Scalar(0));
cv::Mat temp1(grayed.size(), CV_8UC1);
cv::Mat element1 = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
bool done;
do {
    cv::morphologyEx(temp, temp1, cv::MORPH_OPEN, element1);
    cv::bitwise_not(temp1, temp1);
    cv::bitwise_and(temp, temp1, temp1);
    cv::bitwise_or(skel, temp1, skel);
    cv::erode(temp, temp, element1);

    double max;
    cv::minMaxLoc(temp, 0, &max);
    done = (max == 0);

} while (!done);

    //contour
vector<vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
findContours( skel, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

Mat drawing = Mat::zeros( skel.size(), CV_8UC3 );

for( int i = 0; i< contours.size(); i++ ) {

    std::vector<cv::Point> contour_line;
    cv::approxPolyDP(cv::Mat(contours[i]), contour_line, 5, true);
    int nc = (int)contour_line.size();
    const cv::Point * pc = &(contour_line[0]);
    cv::polylines( drawing, &pc, &nc, 1, 0, cv::Scalar(255, 255, 255), nc, FILLED);
    drawContours(drawing, contours, i, Scalar(200, 200, 0), FILLED);
}
return MatToUIImage(drawing);

Question

I have followed this tutorial for Morphological Skeleton. The input and the skeleton result are here.

After performing morphological Skeleton operation, I'm processing findContours and filling it with drawContours. However the end result is not as expected. It thickens the border of each letter instead of filling. Could anyone advice what am I missing? Or do I need to perform any other operation instead of drawContours?

Note: This is most likely a follow-up question of my previous one.