2013-10-31 77 views
1

我有一個墊子的投資回報扭曲的問題。我認爲下面的圖片最好地描述了這個問題。圖像先用cv:cvtColor變成灰色,然後我在灰色墊子上使用cv :: threshold,然後在閾值墊子上使用Canny,然後找到輪廓。我遍歷所有輪廓,並根據輪廓面積找到最大輪廓。然後我使用drawContour將它用作門檻墊上的遮罩。這就是我使用以下代碼:OpenCV:爲什麼ROI Mat失真?

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; 

我在哪裏錯了?如果你們需要更多的代碼,讓我知道,生病會更樂意發佈更多的代碼......(左圖是提取的(ROI Mat),右圖是我從drawContour獲得的蒙版)。

enter image description here

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

這是我嘗試處理,以獲得牌照的圖片。

+0

我想你不能得到boundingRect的內容只是像這樣,這是一個類似的問題,它可以幫助你解決問題http://stackoverflow.com/questions/10176184/with-opencv-try-to-extract-a-region-of-a-picture-described-by- arrayofarrays – Engine

+0

hmm ..'cv :: boundRect'返回一個'cv :: Rect',你可以使用'cv :: Mat(Mat,Rect)'來提取一個ROI ..你確定Rect返回'cv: :boundingRect'是正確的? – Mailerdaimon

+0

使用調試器確保'region_of_interest'是正確的(沒有寬度或高度<0),並且它是'threshMat'的一部分。同時向我們展示原始圖片和完整的代碼。 – cyriel

回答

0

好吧好吧,我終於找到它了......解決辦法是做到以下幾點,基本上只是應對的ROI圖像到另一個墊:

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