Hello dear OpenCV community.
I’m debugging my code. I keep getting the error: (-215:Assertion failed) src.type() == CV_8UC1.
All the forums say that conversion to gray scale is the solution. But it doesn’t work in my case.
I don’t want help with my code at this point because I don’t want to spend time getting my code ready for the question.
I, simply, want to know how do I check if the type of my image is CV_8UC1. What command in opencv python gives me the type of my image? And what are the other possible types. I saw somewhere there is CV_8UC3. What do these types mean?
Thank you in advance.
Ivan
inspect the .dtype
and .shape
of your numpy array.
np.info(your_array)
does a lot more, can be interesting
8UC1 means uint8, single channel, i.e. numpy shape has two dimension (h,w)
8UC3 means uint8, 3-channel (color), numpy shape is (h,w,3)
Time has passed by. I have gained more experience with OpenCV. I would like to add several details to the perfect crackwitz’s answer that I think would be helpful to the novices like I was at the time of asking this question.
-
The error is called “Assertion failed”. It turns out that opencv functions expect arguments to be of certain types. So, when they get the arguments, first thing they do is they check the type of the arguments. This is what the error means: the argument I gave to my function was of the wrong type.
-
Usually, the arguments of the opencv functions are called “src” and “dst”. Usually, “src” argument goes first. With that in mind the part of the error “scr.type()==CV_8UC1” means that the argument called “src” has the wrong type “CV_8UC1”. Since I know “src” usually goes first, it is my first argument that has the wrong type. Else, I should check the signature of my function in the documentation and find out which place the argument “src” occupies in the list of arguments of the function.
-
The most confusing part is what “CV_8UC1” means. It is the name of a type used in opencv. Here, CV is, kind of, a declaration that this is the name of the type used in the opencv library, 8 means 8 bit data type, U means unsigned, C means “channel”, 1 means the number of channels. Usually, number of bits and signed/unsigned notions are covered at the beginning of a first programming course. For those who don’t know what these are, here is a link: C++ Data Types - GeeksforGeeks. Number of channels is a notion from digital image processing course. Another possible example of an opencv data type is “CV_32SC1”. It means an opencv data type, 32 bits, signed, 1 channel.
-
If the opencv function doesn’t like the type of the argument, we should change it. The way we know what type to change it to is explained in the bullet point 2 above. How to change the type? It turns out opencv understands numpy’s data types and matches its own data types with numpy’s ones exactly. For instance, “CV_8UC3” in opencv is the same as np.uint8 in numpy. Or “CV_32SC1” is the same as np.int32. Moreover, opencv images are the same as numpy arrays. With that in mind, the way to change the the data type of an opencv image is to use numpy’s .astype function. For instance, if img is an opencv image and I want to make it of “CV_8UC1” type, I would just type: img = img.astype(‘uint8’). And then use img in my opencv function. In the same vane, if I want to check the type of my opencv image, I simply do: print(img.dtype). If it prints out, say, uint8, I know for sure it is “CV_8UC?”. But I don’t know the number of channels (that’s why I put the question mark). To find out the number of channels, I simply do: print(img.shape). If the shape has only two numbers, e.g., (780,1240), I know it is a single channel 780x1240pix image. If the shape has 3 number, e.g., (780,1280,3), I know it is a 3 channel 780x1240pix image. What’s interesting, though, is that you can’t covert 1-channel image to 3-channel image and vise versa using numpy. For this operation you have to use opencv native function. To convert 3-channel image to 1 channel image, you can use cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), to convert 1-channel image to 3-channel image you can use cv2.cvtColor(gray,cv2.COLOR_GRAY2RGB).
Let me reiterate again. In no way do I claim I have another answer. crackwitz gave the answer. I, simply, add several details which may seem unnecessary to more experienced users, but can be really helpful for novices.
My man, your explanation was the best, i was trying to correct this for hours, and after your explanation i finnaly understood what was wrong thanks
Man, thank you so much for this. I was stuck on what the error meant and your “np.astype(‘uint8’)” line saved me. I created an account on this forsaken website just to say thank you for your help!