简体   繁体   中英

Convert OpenCV-Python to C++/Objective C

I found this very nice code from @abid-rahman-k to detect a rectangle from image: OpenCV C++/Obj-C: Advanced square detection Now the code is in Python and here it is:

import cv2
import numpy as np

img = cv2.imread('sof.jpg')
img = cv2.resize(img,(500,500))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(gray,127,255,0)
contours,hier = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    if cv2.contourArea(cnt)>5000:  # remove small areas like noise etc
        hull = cv2.convexHull(cnt)    # find the convex hull of contour
        hull = cv2.approxPolyDP(hull,0.1*cv2.arcLength(hull,True),True)
        if len(hull)==4:
            cv2.drawContours(img,[hull],0,(0,255,0),2)

cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

I would like to convert it into Objective C/ C++. This is what I did, but did not work, what did I miss?

- (void)processImage2:(cv::Mat&)image;
{
    cv::Mat img,gray,thresh;

    std::vector<std::vector<cv::Point> > contours;

    //  cv::resize(image.clone(), image, cv::Size(500,500) );

    cvtColor(image,  gray, cv::COLOR_BGR2GRAY );

    cv::threshold(gray, thresh, 127, 255, 0);
    findContours(thresh, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);


    std::vector<cv::Point> hull;
    for (size_t i = 0; i < contours.size(); i++)
    {
        if (cv::contourArea(contours[i])>5000){
            cv::convexHull(contours[i],hull);
           approxPolyDP(hull, hull, 0.1*arcLength(hull, true), true);
            if (hull.size() ==4)
               cv::drawContours(image,hull,0,cv::Scalar(0,255,0),2);

        }
    }


}

Update:

The program runs but after I select the image it crashes and I get this error:

Nov 28 10:26:52 Anas-Basalamahs-MacBook-Air.local OpenCV Tutorial[18861] <Error>: CGBitmapContextCreate: unsupported parameter combination: 0 integer bits/component; 0 bits/pixel; 0-component color space; kCGImageAlphaNone; 0 bytes/row.
Nov 28 10:26:52 Anas-Basalamahs-MacBook-Air.local OpenCV Tutorial[18861] <Error>: CGContextConcatCTM: invalid context 0x0
Nov 28 10:26:52 Anas-Basalamahs-MacBook-Air.local OpenCV Tutorial[18861] <Error>: CGContextSetInterpolationQuality: invalid context 0x0
Nov 28 10:26:52 Anas-Basalamahs-MacBook-Air.local OpenCV Tutorial[18861] <Error>: CGContextDrawImage: invalid context 0x0
Nov 28 10:26:52 Anas-Basalamahs-MacBook-Air.local OpenCV Tutorial[18861] <Error>: CGBitmapContextCreateImage: invalid context 0x0
2012-11-28 10:26:52.963 OpenCV Tutorial[18861:c07] resized image size: NSSize: {0, 0}
OpenCV Error: Assertion failed (i < 0) in getMat, file /Users/bloodaxe/Develop/opencv/modules/core/src/matrix.cpp, line 957
terminate called throwing an exception(lldb) 

Here, this is working:

cv::Mat oResult, oToShow;
// roMat is your input image
cv::cvtColor(roMat, oToShow, CV_GRAY2BGR);

cv::threshold(roMat, oResult, 127, 255, 0);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;

cv::findContours( oResult, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE );


std::vector<std::vector<cv::Point> > oHull(contours.size());
for( int i = 0; i != contours.size(); i++)
{
    if( cv::contourArea(contours[i]) > 5000 )
    {
        cv::convexHull(contours[i], oHull[i]);
        cv::approxPolyDP(oHull[i], oHull[i], 0.1*cv::arcLength(oHull[i], true), true);
        if( oHull[i].size() == 4 )
        {
            cv::drawContours(oToShow, oHull, -1, cv::Scalar(0, 255,0), 2, 8);
        }

    }
}

cv::imshow("hull", oToShow);
cv::waitKey(0);

I think the error was, that you actually got an Array of Hulls, and not just one Hull.

I don't see an imread in your code, so I'm assuming you are reading the image outside this function and passing it in. Have you tried doing an imshow right after reading to ensure the image is correctly loaded.

The first line indicates to me that that could be the problem.

The problem is in cv::drawContours(image,hull,0,cv::Scalar(0,255,0),2);

for some reason, it doesn't like the hull array... So I suppose something wrong is happening in one of those lines:

cv::convexHull(contours[i],hull);

approxPolyDP(hull, hull, 0.1*arcLength(hull, true), true);

(you don't say Sherlock!)

I tried to find a solution playing with the code from those links:

I hope the will help you more than they did to me.

Also, sorry for posting it as an answer... but my reputation was low and I could not add comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM