2017-05-01 13 views
13

मैं एक A4 कागज की एक छवि के लिए अनुकूली थ्रेशोल्डिंग लागू करने के लिए कोशिश कर रहा हूँ पर एक छवि के लिए अनुकूली सीमा लागू करने के लिए:OpenCV - नीचे दिखाया गया है कैसे आईओएस

मैं लागू करने के लिए नीचे दिए गए कोड का उपयोग छवि हेरफेर:

+ (UIImage *)processImageWithOpenCV:(UIImage*)inputImage { 
    cv::Mat cvImage = [inputImage CVMat]; 
    cv::Mat res; 
    cv::cvtColor(cvImage, cvImage, CV_RGB2GRAY); 
    cvImage.convertTo(cvImage,CV_32FC1,1.0/255.0); 
    CalcBlockMeanVariance(cvImage,res); 
    res=1.0-res; 
    res=cvImage+res; 
    cv::threshold(res,res, 0.85, 1, cv::THRESH_BINARY); 
    cv::resize(res, res, cv::Size(res.cols/2,res.rows/2)); 
    return [UIImage imageWithCVMat:cvImage]; 
} 

void CalcBlockMeanVariance(cv::Mat Img,cv::Mat Res,float blockSide=13) // blockSide - the parameter (set greater for larger font on image) 
{ 
cv::Mat I; 
Img.convertTo(I,CV_32FC1); 
Res=cv::Mat::zeros(Img.rows/blockSide,Img.cols/blockSide,CV_32FC1); 
cv::Mat inpaintmask; 
cv::Mat patch; 
cv::Mat smallImg; 
cv::Scalar m,s; 

for(int i=0;i<Img.rows-blockSide;i+=blockSide) 
{ 
    for (int j=0;j<Img.cols-blockSide;j+=blockSide) 
    { 
     patch=I(cv::Rect(j,i,blockSide,blockSide)); 
     cv::meanStdDev(patch,m,s); 
     if(s[0]>0.01) // Thresholding parameter (set smaller for lower contrast image) 
     { 
      Res.at<float>(i/blockSide,j/blockSide)=m[0]; 
     }else 
     { 
      Res.at<float>(i/blockSide,j/blockSide)=0; 
     } 
    } 
} 

cv::resize(I,smallImg,Res.size()); 

cv::threshold(Res,inpaintmask,0.02,1.0,cv::THRESH_BINARY); 

cv::Mat inpainted; 
smallImg.convertTo(smallImg,CV_8UC1,255); 

inpaintmask.convertTo(inpaintmask,CV_8UC1); 
inpaint(smallImg, inpaintmask, inpainted, 5, cv::INPAINT_TELEA); 

cv::resize(inpainted,Res,Img.size()); 
Res.convertTo(Res,CV_8UC3); 

} 

हालांकि inputted छवि greyscaled है, यह एक पीले रंग छवि के रूप में नीचे दिखाया गया है आउटपुट:

मेरी परिकल्पना यह है कि सीवी :: मैट और यूआईएममेज के बीच रूपांतरण, कुछ रंग छवि की ओर अग्रसर हुआ, हालांकि मैं इस मुद्दे को ठीक करने का तरीका नहीं समझ सकता।

** कृपया स्टेटस बार को अनदेखा करें क्योंकि ये छवियां आईओएस ऐप के स्क्रीनशॉट हैं।

अद्यतन: मैं Res.convertTo() के लिए CV_8UC1 बजाय CV_8UC3 उपयोग करने की कोशिश और cvtColor(Res, Res, CV_GRAY2BGR); जोड़ा है, लेकिन अभी भी बहुत इसी तरह के परिणाम हो रही है है।

क्या यह सीवी :: मैट और यूआईएममेज के बीच रूपांतरण हो सकता है जो इस समस्या का कारण बन रहा है ??

मैं चाहता हूं कि मेरी छवि नीचे दिखाए गए जैसा हो।

+0

आप '' CV_32FC1' रूप Res' प्रारंभ है उत्पादन की जाँच करें, और के लिए काम तो आप 'Res.convertTo (रेस, CV_8UC3) का उपयोग कर uchar'' करने के लिए इसे परिवर्तित कर रहे हैं; ', जो फिश लग रहा है, 'Res.convertTo (Res, CV_8UC1) के साथ प्रयास करें;' और बाद में 'cvtColor' – ZdaR

+0

@ZdaR का उपयोग करें, क्या आप कृपया' cvtColor' 'का उपयोग करके इसका अर्थ बता सकते हैं? मैंने 'सीवी_8 यूसी 1 'की कोशिश की है जिसके बाद' सीवीटीकॉलर (रेस, रेस, सीवी_जीआरई 2 बीजीआर); '। हालांकि, मुझे अभी भी बहुत ही समान परिणाम मिल रहे हैं। कोई अन्य सुझाव? –

उत्तर

5

आप OpenCV ढांचे का उपयोग और कोड नीचे लागू कर सकते हैं

+(UIImage *)blackandWhite:(UIImage *)processedImage 
    { 
     cv::Mat original = [MMOpenCVHelper cvMatGrayFromAdjustedUIImage:processedImage]; 

     cv::Mat new_image = cv::Mat::zeros(original.size(), original.type()); 

     original.convertTo(new_image, -1, 1.4, -50); 
     original.release(); 

     UIImage *blackWhiteImage=[MMOpenCVHelper UIImageFromCVMat:new_image]; 
     new_image.release(); 

     return blackWhiteImage; 
    } 

+ (cv::Mat)cvMatGrayFromAdjustedUIImage:(UIImage *)image 
{ 
    cv::Mat cvMat = [self cvMatFromAdjustedUIImage:image]; 
    cv::Mat grayMat; 
    if (cvMat.channels() == 1) { 
     grayMat = cvMat; 
    } 
    else { 
     grayMat = cv :: Mat(cvMat.rows,cvMat.cols, CV_8UC1); 
     cv::cvtColor(cvMat, grayMat, cv::COLOR_BGR2GRAY); 
    } 
    return grayMat; 
} 

+ (cv::Mat)cvMatFromAdjustedUIImage:(UIImage *)image 
{ 
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); 
    CGFloat cols = image.size.width; 
    CGFloat rows = image.size.height; 

    cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels 

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,     // Pointer to backing data 
                cols,      // Width of bitmap 
                rows,      // Height of bitmap 
                8,       // Bits per component 
                cvMat.step[0],    // Bytes per row 
                colorSpace,     // Colorspace 
                kCGImageAlphaNoneSkipLast | 
                kCGBitmapByteOrderDefault); 

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); 
    CGContextRelease(contextRef); 
    return cvMat; 
} 


+ (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat 
{ 
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()]; 

    CGColorSpaceRef colorSpace; 

    if (cvMat.elemSize() == 1) { 
     colorSpace = CGColorSpaceCreateDeviceGray(); 
    } else { 
     colorSpace = CGColorSpaceCreateDeviceRGB(); 
    } 

    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 

    CGImageRef imageRef = CGImageCreate(cvMat.cols,          // Width 
             cvMat.rows,          // Height 
             8,            // Bits per component 
             8 * cvMat.elemSize(),       // Bits per pixel 
             cvMat.step[0],         // Bytes per row 
             colorSpace,          // Colorspace 
             kCGImageAlphaNone | kCGBitmapByteOrderDefault, // Bitmap info flags 
             provider,          // CGDataProviderRef 
             NULL,           // Decode 
             false,           // Should interpolate 
             kCGRenderingIntentDefault);      // Intent 

    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef]; 
    CGImageRelease(imageRef); 
    CGDataProviderRelease(provider); 
    CGColorSpaceRelease(colorSpace); 

    return image; 
} 

इसकी मुझे अपने दस्तावेज़

+0

हे धन्यवाद, क्या आप एक उदाहरण दे सकते हैं? –

+0

मैंने पूर्ण कामकाजी कोड डाला है .., बस अपनी छवि को संसाधित करने के लिए पास करें + (UIImage *) BlackandWhite: (UIImage *) संसाधित छवि विधि –

+0

इस कोड से परिणाम का एक उदाहरण –

3

इस प्रयास करें:

+ (UIImage *)processImageWithOpenCV:(UIImage*)inputImage { 
    cv::Mat cvImage = [inputImage CVMat]; 
    threshold(cvImage, cvImage, 128, 255, cv::THRESH_BINARY); 
    return [UIImage imageWithCVMat:cvImage]; 
} 

परिणाम छवि:

+0

हालांकि यह एक प्रकार का थ्रेसहोल्डिंग है और यह काम करता है, मैं अनुकूली थ्रेसहोल्डिंग को कार्यान्वित करना चाहता हूं क्योंकि यह बेहतर परिणाम चलाएगा - अनुकूली थ्रेसहोल्डिंग के विनिर्देश यहां पाए जा सकते हैं; http://hanzratech.in/2015/01/21/adaptive-thresholding.html –

संबंधित मुद्दे