Question

I'm playing around with iOS and OpenCV trying to create a game which converts basically any image to a black and white colorable image where there are multiple closed areas and we can color these areas with only a tap on the screen. So far I have partial success. The conversion works fine, but I'm stuck at creating an image with concrete colorable (closed) areas.

Is it even possible? If not what alternative methods/ideas do you suggest? I have two, but I like neither.
  - we define areas by drawing after the conversion
  - the tap on the screen only does the recursive search for x pixels

Example: Dropbox pics

Any constructive help is greatly appreciated!

My view controller's related part:

- (void)viewDidLoad{
    [super viewDidLoad];

    imageProcessor = [[Conversion alloc] init];

    _image = [UIImage imageNamed:@"lenna"];
    imageProcessor.thresholdSlider = self.thresholdSlider;
    imageProcessor.thresholdSlider2 = self.thresholdSlider2;

    self.imageView.image = [imageProcessor convertImage:_image]; 
}

- (IBAction)sliderChanged:(id)sender {
    self.imageView.image = [imageProcessor convertImage:_image];
}

And the Conversion class's related part using OpenCV

- (UIImage*)convertImage:(UIImage*)image{

    cv::Mat src;
    cv::Mat src_gray;

    //Convert UIImage to cv::Mat
    src = [self cvMatFromUIImage:image];

    if (!src.empty()) {
        //Convert cv::Mat to grayscale
        cv::cvtColor(src, src_gray, CV_RGBA2GRAY);
        cv::blur(src_gray, src_gray, cv::Size(3,3));

        cv::Mat canny_output;
        cv::vector<cv::vector<cv::Point> > contours;
        cv::vector<cv::Vec4i> hierarchy;

        int thresh = (int)self.thresholdSlider.value;
        int thresh2 = (int)self.thresholdSlider2.value;

        NSLog(@"%d, %d", thresh, thresh2);

        //Detect edges using canny
        //http://en.wikipedia.org/wiki/Canny_edge_detector
        cv::Canny(src_gray, canny_output, thresh, thresh2, 3, true);

        //InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method,
        //Point offset = Point())
        cv::findContours(canny_output, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0,0));

        cv::Scalar blackColor = cv::Scalar::all(0);
        cv::Scalar whiteColor = cv::Scalar::all(255);

        //create a WHITE Mat with the canny_output size
        cv::Mat drawing(canny_output.size(), CV_8UC3, whiteColor);
        for (size_t i = 0; i < contours.size(); i++) {
            //InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar &color, int thickness = 1,
            //int lineType = 8, InputArray hierarchy = noArray(), int maxLevel = 2147483647, Point offset = Point())
            cv::drawContours(drawing, contours, int(i), blackColor, 1, CV_AA, hierarchy, INT_MAX, cv::Point());
        }
        return [self UIImageFromCVMat:drawing];

    }
    return nil;
}
Was it helpful?

Solution

You can follow this steps,

  1. Find contour.

  2. For each contour check whether its closed or not as explained here, and then draw the contour with appropriate color.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top