0

I am developing an App that detects red little rectangles from an image. I have a code (gotten from this answer here) that apparently does that.

The code states that I need to use the imread() method with the String file name as a parameter.

The steps: I open the camera. I take a picture, display it on screen and save it to the App's file directory. Then, using the code mentioned, I use the imread() to reference the image and get the job done.

I don't know if I am doing something wrong or what, but mask.data ALWAYS returns NULL. I believe that the problem lies on the imread() file path given wrong, thus Mat3b brg is empty, and then the error is created.

Can someone enlighten me on that?

Below is the code I got so far:

//The snippet begins after the picture is taken

//First Part of Method - closing the camera and adding the result view
[photoCam stop];

resultView = [[UIImageView alloc] initWithFrame:imageView.bounds];
UIImage* result = image;
[resultView setImage:result];
resultView.center = imageView.center;
[self.view addSubview:resultView];

//Second Part of the Method - saving the image to a file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"image.png"];
[UIImagePNGRepresentation(result) writeToFile:filePath atomically:YES];

//Third Part of the Method - reading the red rectangles
Mat3b bgr = cv::imread("image.png"); // Here is where I believe the problem is. HELP!!!!
//Already tried the absolute path of the image, like 
// "/var/mobile/Containers/Data/Application/BAB824A7-C7C1-4D1E-BB4A-43A003F30F1A/Documents/image.png"
// Didn't work either.

Mat3b hsv;
cvtColor(bgr, hsv, COLOR_BGR2HSV);

Mat1b mask1, mask2;
inRange(hsv, Scalar(0, 70, 50), Scalar(10, 255, 255), mask1);
inRange(hsv, Scalar(170, 70, 50), Scalar(180, 255, 255), mask2);

Mat1b mask = mask1 | mask2;

if (mask.data == NULL)
{
    NSLog(@"mask.data == null");
}
else
{
    namedWindow("Mask", CV_WINDOW_AUTOSIZE);
    imshow("Mask", mask);
    waitKey();
}

Thanks in advance.

gbossa
  • 377
  • 1
  • 3
  • 18
  • try to use the absolute path to the image. Probably your working directory is not where you expect it. – Micka Jul 24 '20 at 04:53
  • Thanks for the reply. I already tried it, but the error is the same. I got the path printing on log the `filePath` var. – gbossa Jul 24 '20 at 12:51
  • does your application have permissions to access the file/directory? Can you try to write a file, like "test.txt"? – Micka Jul 24 '20 at 13:15
  • have a look at: https://answers.opencv.org/question/13360/imread-in-ios/ – Micka Jul 24 '20 at 13:16
  • Hey! Your tip did the trick. Now I get value on `mask.data`. I am getting another error though. But for the matter of this question, you helped me solve it. Post your comment as an answer so I can accept and upvote it! FYI, I will post the error I am getting now, in comment below: – gbossa Jul 24 '20 at 13:32
  • `OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvNamedWindow, file /Volumes/build-storage/build/master_iOS-mac/opencv/modules/highgui/src/window.cpp, line 593 libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /Volumes/build-storage/build/master_iOS-mac/opencv/modules/highgui/src/window.cpp:593: error: (-2)` It says something about Linux, and Windows, but I am using Mac OS. – gbossa Jul 24 '20 at 13:32
  • your system doesnt allow you ro create a namedWindow and imshow. Not sure about how to solve that in iOs. Maybe you can use native functions to show images? – Micka Jul 24 '20 at 14:58
  • please write the answer yourself, I'll upvote the solution – Micka Jul 24 '20 at 14:59

1 Answers1

0

After getting help from Micka, I found the solution for the problem.

I was trying to read the image using the imread() method, which was not finding the file path (no matter what path I used), hence not returning anything, so in the end mask.data was returning NULL.

Micka suggested me to read this tread posted on OpenCV's official forum. In the first answer there, someone suggested that the image is passed as a parameter using UIImage, rather than using the path of the file. So, this is what I did, and voilá, mask.data is returning the value of the image.

Here is the code which did the trick:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"image.png"];
[UIImagePNGRepresentation(result) writeToFile:filePath atomically:YES];

UIImage* resImage = [UIImage imageWithContentsOfFile:filePath];
cv::Mat3b bgr;
UIImageToMat(resImage, bgr);

Mat3b hsv;
cvtColor(bgr, hsv, COLOR_BGR2HSV);

Thanks Micka!

gbossa
  • 377
  • 1
  • 3
  • 18