2

Im having an issue where the ROI of an mat get distorted. I think the image below describes the problem best. The image is first turned gray with cv:cvtColor, then i use cv::threshold on the gray mat, then i use Canny on the threshold mat, then i find the contours. I go through all the contours and find the biggest contour based on area of the contour. I then use drawContour to use it as a mask on the threshold mat. And thats where i use the following code:

cv::Mat inMat = [self cvMatFromUIImage: inputImage];
cv::Mat grayMat, threshMat, canny_output;
cv::cvtColor(inMat, grayMat, CV_BGR2GRAY);
cv::threshold(grayMat, threshMat, 128, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

Canny(threshMat, canny_output, 100, 100, 3);
cv::Mat drawing = cv::Mat::zeros( canny_output.size(), CV_8UC3 );
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point> > contours;
cv::findContours(canny_output, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
NSMutableArray *contourAreasArray = [NSMutableArray new];
// Sorts the contour areas from greatest or smallest

for (int i = 0; i < contours.size(); ++i) {
    NSNumber *contourArea = [NSNumber numberWithDouble:cv::contourArea(contours[i])];
    [contourAreasArray addObject:contourArea];
}

NSSortDescriptor *highestToLowest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
[contourAreasArray sortUsingDescriptors:[NSArray arrayWithObject:highestToLowest]];

cv::Rect maskRect;
Mat mask;
for (int i = 0; i < contours.size(); ++i)
{
    NSNumber *contourArea = [NSNumber numberWithDouble:cv::contourArea(contours[i])];
    cv::Rect brect = cv::boundingRect(contours[i]);

    if ([contourArea doubleValue] == [[contourAreasArray objectAtIndex:0] doubleValue]) {
        //NSLog(@"Drawing Contour");
        maskRect = cv::boundingRect(contours[i]);
        cv::drawContours(drawing, contours, i, cvScalar(255,255,255), CV_FILLED);
        cv::rectangle(drawing, brect, cvScalar(255));
    }
}

cv::Rect region_of_interest = maskRect;
cv::Mat roiImage = cv::Mat(threshMat, region_of_interest);

// final result is converted to UIImage for display
UIImage *threshUIImage = [self UIImageFromCVMat:drawing];
UIImage *resultUIImage = [self UIImageFromCVMat:roiImage];
self.plateImageView.image = resultUIImage;
self.threshImageView.image = threshUIImage;

Where am i going wrong here? If you guys need more code let me know, ill be more than happy to post more code... (the left image is the extracted (ROI Mat) and the right one is the mask that i obtain from drawContour).

enter image description here

The image I'm trying to process. (Basically getting the license plate)

And this is the picture I'm trying to process to get the license plate.

Community
  • 1
  • 1
  • I think you can't get the content of boundingRect just like that here's a similar question it may help you to solve the problem http://stackoverflow.com/questions/10176184/with-opencv-try-to-extract-a-region-of-a-picture-described-by-arrayofarrays – Engine Oct 31 '13 at 08:00
  • hmm.. `cv::boundRect` returns a `cv::Rect` and you can use `cv::Mat(Mat,Rect)` to extract a ROI.. are you sure the Rect returned by `cv::boundingRect` is correct? – Mailerdaimon Oct 31 '13 at 08:30
  • Use debugger to make sure that `region_of_interest` is correct(doesn't have width or height < 0) and that it's part of `threshMat`. Also show us original image and full code. – cyriel Oct 31 '13 at 14:12
  • cv:boundingRect is returning values greater than 0 `(x:258,y:354,w:174,h:41)`. I edited my question with more code. Any ideas? – Sero Eskandaryan Oct 31 '13 at 16:08

1 Answers1

1

Alright well i finally figured it out...the solution was to do the following, essentially just coping the ROI image into another Mat:

cv::Rect region_of_interest = maskRect;
cv::Mat roiImage = cv::Mat(threshMat, region_of_interest);
cv::Mat finalROIImage;
roiImage.copyTo(finalROIImage);