2

I have been trying for hours to run an xcode project with openCV. I have built the source, imported it into the project and included #ifdef __cplusplus #import opencv2/opencv.hpp> #endif in the .pch file.

I followed the instructions from http://docs.opencv.org/trunk/doc/tutorials/introduction/ios_install/ios_install.html

Still I am getting many Apple Mach-O linker errors when I compile.

Undefined symbols for architecture i386:
 "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:

Please help me I am really lost..

UPDATE:

Errors all fixed and now I am trying to detect circles..

Mat src, src_gray;

cvtColor( image, src_gray, CV_BGR2GRAY );

vector<Vec3f> circles;

/// Apply the Hough Transform to find the circles
HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, image.rows/8, 200, 100, 0, 0 );


/// Draw the circles detected
for( size_t i = 0; i < circles.size(); i++ )
{
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    int radius = cvRound(circles[i][2]);
    // circle center
    circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );
    // circle outline
    circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );


}

I am using the code above, however no circles are being drawn on the image.. is there something obvious that I am doing wrong?

foundry
  • 31,615
  • 9
  • 90
  • 125
dev
  • 900
  • 2
  • 12
  • 26

1 Answers1

8

Try the solution in my answer to this question...

How to resolve iOS Link errors with OpenCV

Also on github I have a couple of simple working samples - with recently built openCV framework.

NB - OpenCVSquares is simpler than OpenCVSquaresSL. The latter was adapted for Snow Leopard backwards compatibility - it contains two builds of the openCV framework and 3 targets, so you are better off using the simpler OpenCVSquares if it will run on your system.

To adapt OpenCVSquares to detect circles, I suggest that you start with the Hough Circles c++ sample from the openCV distro, and use it to adapt/replace CVSquares.cpp and CVSquares.h with, say CVCircles.cpp and CVCicles.h

The principles are exactly the same:

  • remove UI code from the c++, the UI is provided on the obj-C side
  • transform the main() function into a static member function for the class declared in the header file. This should mirror in form an Objective-C message to the wrapper (which translates the obj-c method to a c++ function call).

From the objective-C side, you are passing a UIImage to the wrapper object, which:

  • converts the UIImage to a cv::Mat image
  • pass the Mat to a c++ class for processing
  • converts the result from Mat back to UIImage
  • returns the processed UIImage back to the objective-C calling object

update

The adapted houghcircles.cpp should look something like this at it's most basic (I've replaced the CVSquares class with a CVCircles class):

cv::Mat CVCircles::detectedCirclesInImage (cv::Mat img)
{   
    //expects a grayscale image on input
    //returns a colour image on ouput
    Mat cimg;
    medianBlur(img, img, 5);
    cvtColor(img, cimg, CV_GRAY2RGB);
    vector<Vec3f> circles;
    HoughCircles(img, circles, CV_HOUGH_GRADIENT, 1, 10,
                 100, 30, 1, 60 // change the last two parameters
                 // (min_radius & max_radius) to detect larger circles
                 );
    for( size_t i = 0; i < circles.size(); i++ )
        {
        Vec3i c = circles[i];
        circle( cimg, Point(c[0], c[1]), c[2], Scalar(255,0,0), 3, CV_AA);
        circle( cimg, Point(c[0], c[1]), 2, Scalar(0,255,0), 3, CV_AA);
        }
    return cimg;
    }

Note that the input parameters are reduced to one - the input image - for simplicity. Shortly I will post a sample on github which will include some parameters tied to slider controls in the iOS UI, but you should get this version working first.

As the function signature has changed you should follow it up the chain...

Alter the houghcircles.h class definition:

    static cv::Mat detectedCirclesInImage (const cv::Mat image);

Modify the CVWrapper class to accept a similarly-structured method which calls detectedCirclesInImage

    + (UIImage*) detectedCirclesInImage:(UIImage*) image
    {
        UIImage* result = nil;
        cv::Mat matImage = [image CVGrayscaleMat];
        matImage = CVCircles::detectedCirclesInImage (matImage);
        result = [UIImage imageWithCVMat:matImage];
        return result;
    }

Note that we are converting the input UIImage to grayscale, as the houghcircles function expects a grayscale image on input. Take care to pull the latest version of my github project, I found an error in the CVGrayscaleMat category which is now fixed . Output image is colour (colour applied to grayscale input image to pick out found circles).

If you want your input and output images in colour, you just need to ensure that you make a grayscale conversion of your input image for sending to Houghcircles() - eg cvtColor(input_image, gray_image, CV_RGB2GRAY); and apply your found circles to the colour input image (which becomes your return image).

Finally in your CVViewController, change your messages to CVWrapper to conform to this new signature:

    UIImage* image = [CVWrapper detectedCirclesInImage:self.image];

If you follow all of these details your project will produce circle-detected results.

update 2
OpenCVCircles now on Github
With sliders to adjust HoughCircles() parameters

Community
  • 1
  • 1
foundry
  • 31,615
  • 9
  • 90
  • 125
  • Thankyou. That is quite helpful. I am currently trying to modify your OpenCVSquaresSL project to detect circles instead, is there a lot to change in your project, or would I be better off starting a new project using yours as a guideline? – dev Jan 19 '13 at 18:06
  • Which versions of XCode and OSX are you using? – foundry Jan 19 '13 at 18:12
  • Hello, thank you for your reply. I am using XCode 4.5.2 and OSX 10.7.5 PS. I forgot to mention that all is compiling properly now, and as mentioned above, I would really love to be able to detect circles instead of squares – dev Jan 19 '13 at 18:13
  • @Pluto - see my update - I will expand this answer a little if you check back later – foundry Jan 19 '13 at 18:43
  • Thank you very much for your kind help sir. I will be honest in saying I am trying my best to port it over for hours. I am still having trouble adapting your code to find circles, If you have some time, please show me some sample code.. I am truly lost – dev Jan 19 '13 at 19:26
  • Do I have to find contours when detecting circles? – dev Jan 19 '13 at 19:47
  • @Pluto - No. The only function you need is `HoughCircles()` - this line in `houghcircles.cpp`: `HoughCircles(img, circles, CV_HOUGH_GRADIENT, 1, 10,100, 30, min_radius, max_radius);` You do need to make a few other adjustments to the main()function as it expects grayscale input.. i will update my answer shortly – foundry Jan 19 '13 at 21:11
  • Hello, my sincerest thanks. I am still working on this, and the last element seems to be the showing up the updated image once the circles from HoughCircles have been found. I look forward to your update.. – dev Jan 19 '13 at 21:34
  • No Im afraid not, I cannot get the circles to show up on the picture.. I updated my code above. All of the above code is simply being placed in cv::Mat CVSquares::detectedSquaresInImage (cv::Mat image, float tol, int threshold, int levels, int acc)... Any idea why the circles are not showing around the circular parts of the image? – dev Jan 19 '13 at 22:27
  • @pluto, this question is in danger of wandering too much from the original. Can you tick it as accepted, and I will provide my latest answer in [your follow-up question](http://stackoverflow.com/questions/14417380/opencv-detect-circles-in-ios) – foundry Jan 19 '13 at 23:09
  • @pluto, I have updated THIS answer with enough detail. If you still have issues please open a new question. – foundry Jan 19 '13 at 23:38
  • Wow. That you so very much. You have completely solved my problem, I can now plough ahead! Thanks again buddy. Now I will work on detecting the correct circles! – dev Jan 20 '13 at 10:26
  • Sorry, last question buddy.. is it possible to return a colored(RGB) image when circles are found? – dev Jan 20 '13 at 15:43
  • @Pluto, yes it is possible, see expanded answer. – foundry Jan 21 '13 at 01:13
  • I am finding it impossible to convert the output image to RGB. Your code is not allowing it. Please tell me what to change!!! Also your CVCircles.cpp seems to be changing the color to RGB already cvtColor(img, cimg, CV_GRAY2RGB); so I am wondering why is it still grey on output? – dev Jan 27 '13 at 14:19
  • 1
    It is converting to colour to colourise the found circles. To fix the input-output colour issue, can you raise a new question, showing the code, and I will help you out. – foundry Jan 27 '13 at 15:50
  • Hello, thank you for your reply. New question here http://stackoverflow.com/questions/14571790/convert-image-color-from-grayscale-to-rgb-opencv-c – dev Jan 28 '13 at 21:44
  • Any chance you can take a look at [my problem](http://stackoverflow.com/questions/21232694/opencv-framework-symbols-not-found-for-architecture-armv7)? I've changed the c++ compiler, but I'm still getting the error. If I use libstdc++ I get those errors, if I use libc++ I get a more general error (still about not having symbols). – fredley Jan 20 '14 at 12:03