Ask Your Question
0

error handling with imread()

asked 2019-01-08 11:21:49 -0600

GXY gravatar image

Hello all, i am having a problem with the error handling in terms of the API "imread()". If i pass as command line a false file name, like "foobar" created randomly by "touch foobar" in bash. In my code i wrap the "imread()" into a try-catch block as follows:

cv:: Mat src;
try
   {   
         src =imread(argv[1]);
   }
   catch( cv::Exception& e )
   {
         //const char* err_msg = e.what();
         //std::cout << "exception caught: " << err_msg << std::endl;
         cout <<"wrong file format, please input the name of an IMAGE file" <<endl;
     return -1;
   }

i commented the error message in catch block because i just want the program to exit. However, when i execute the program it still prints the following error message to stdout and the catch block is never executed:

terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr: __pos (which is 140) > this->size() (which is 0) Aborted (core dumped)

I know this message comes from c++ standard library and i can't change them, is there still any way to get rid of the error message? the program is aborted now, what i am expecting is that it goes into the catch block and print something that can be specified by the programmer, like "wrong file format, please input the name of an IMAGE file"?

Besides, i'm using xubuntu 18.04 and opencv 3.2.0, thanks in advance!

edit retag flag offensive close merge delete

Comments

from the documentation "If the image cannot be read (because of missing file, improper permissions, unsupported or invalid format), the function returns an empty matrix ( Mat::data==NULL )."

sturkmen gravatar imagesturkmen ( 2019-01-08 11:44:27 -0600 )edit

can you try to update to a more recent opencv version, which has better error handling there ?

3.2.0 vs. master

berak gravatar imageberak ( 2019-01-09 03:33:40 -0600 )edit

I will try it as the last option, but IMO, 3.2.0 is recent enough for "imread()" as the program doesn't terminate on ubuntu 16.04 with the same version, i.e., 3.2.0 of OpenCV, even passed with a file with the false format. What are you trying to say by linking the above links? I see no difference between them in the source code from "maxlen = fread( (void*)signature.c_str(), 1, maxlen, f );" to "static ImageEncoder findEncoder( const String& _ext )"

GXY gravatar imageGXY ( 2019-01-09 04:58:26 -0600 )edit

well it may be, just don't give it empty files ;)

opencv uses std::string, 3.2 uses a "selfmade" cv::String, and imho, that one does not like substr(0,0) on an empty String. (don't have 3.2 around, so i can't prove it, but maybe you can make a small test ?)

berak gravatar imageberak ( 2019-01-09 05:04:45 -0600 )edit

I myself know of course how to run the program properly and won't give it an empty file, the thing is that I can't assume that my client user also knows how, so it's my task to consider all possibilities what may be passed by the client user. If the user passes an empty file I want to notify them that an image file should be passed, rather than the program just terminates. This can already be accomplished on ubuntu 16.04 with OpenCV 3.2.0 installed by checking "if(src.empty())", but on Xubuntu 18.04 with the same version of OpenCV the program just terminates at "imread()". What should i test exactly?

GXY gravatar imageGXY ( 2019-01-09 05:40:47 -0600 )edit

1 answer

Sort by » oldest newest most voted
2

answered 2019-01-08 11:36:57 -0600

berak gravatar image

updated 2019-01-08 11:41:14 -0600

you're wrong about cv::imread() throwing an exception, it won't ever happen.

instead, please check for src.empty() like:

 if (src.empty()) {
     // fail, bail out !
     return -1; 
}
edit flag offensive delete link more

Comments

1

The thing is that my program terminates at the line where imread() is called in the described situation, anything left, including what you‘ve suggested, will even not be executed.

GXY gravatar imageGXY ( 2019-01-08 12:26:45 -0600 )edit

so , go back to argv[1] (in your program). most probably that's an invalid path.

berak gravatar imageberak ( 2019-01-08 12:40:38 -0600 )edit

being around a long time, i have personally no idea, how we can mend the ususal sillines of noobs here.

berak gravatar imageberak ( 2019-01-08 12:45:45 -0600 )edit

I can run the program successfully, i‘ve fabricated such a situation on purpose, in which my client user, who has no knowledge about opencv or image processing, passes an arbitrary file, which is not an image. I would like to notify my user that an image file should be passed before the program terminates. How can I achieve then?

GXY gravatar imageGXY ( 2019-01-08 12:57:53 -0600 )edit

again, check `src.empty() -- donot rely on exceptions.

berak gravatar imageberak ( 2019-01-08 13:00:06 -0600 )edit

and no, you can NEVER expect, what your stupid user does ;)

what you want , is instead nailing it down to a single point of failure

berak gravatar imageberak ( 2019-01-08 13:01:48 -0600 )edit

As i wrote above, on xubuntu 18.04 with opencv 3.2, imread() terminates immediately when the passed argument is not an image file, there is even no chance to call src.empty(). Btw, I am wondering if you guys can reproduce this error

GXY gravatar imageGXY ( 2019-01-08 13:16:57 -0600 )edit

please augment * your question* with a minimal, reprodcucing test case.

berak gravatar imageberak ( 2019-01-08 13:20:05 -0600 )edit

It’s just a function call to imread(), and my question is how can i bypass the termination of program caused by not passing an image file, platform is xubuntu 18.04 with opencv 3.2, I mention this because I myself cannot reproduce it on ubuntu 16.04 with opencv 3.2.

GXY gravatar imageGXY ( 2019-01-08 13:38:20 -0600 )edit
1

may be exception is thrown by 3rd party lib

LBerger gravatar imageLBerger ( 2019-01-08 13:56:01 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2019-01-08 11:21:49 -0600

Seen: 13,464 times

Last updated: Jan 08 '19