0
votes

i have a problem with cv2.cvtColor in my code:

sct_img = self.screen.grab(self.monitor)
img = Image.frombytes('RGB', sct_img.size, sct_img.rgb)
img = np.array(img)
img = self.convert_rgb_to_bgr(img)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 218])
upper = np.array([157, 54, 255])
mask = cv2.inRange(hsv, lower, upper)
... 

Error:

cv2.error: OpenCV(4.2.0) c:\projects\opencv-python\opencv\modules\imgproc\src\color.simd_helpers.hpp:92: error: (-2:Unspecified error) in function '__cdecl cv::impl::`anonymous-namespace'::CvtHelper<struct cv::impl::`anonymous namespace'::Set<3,4,-1>,struct cv::impl::A0x3b52564f::Set<3,-1,-1>,struct cv::impl::A0x3b52564f::Set<0,5,-1>,2>::CvtHelper(const class cv::_InputArray &,const class cv::_OutputArray &,int)'
> Invalid number of channels in input image:
>     'VScn::contains(scn)'
> where
>     'scn' is 1

I've tested it before where I imported my image already grayscaled with "img = cv2.imread(image_path)" and then the part with hsv ... It was working perfectly but now where I take a screenshot wile running and tried it grayscale with "cv2.COLOR_BGR2GRAY" I get this error above. When I delete that line, I will not getting any errors but the image is not that thresholded I want. So its necessary that the image is grayscaled before my code continue with hsv...

I hope somebody have an solution for me, thanks in advance!

1
You cannot convert from single channel gray to 3 channel HSV using cvtColor. You need to convert the gray to 3 channel. But then you would get 0 hue, 0 saturation, and V = your original gray image. So that does nothing for you.fmw42
@fmw42, thanks for retelling my answer?Powercoder
@Powercoder Sorry, I had not noticed. Full credit to you since you apparently posted first. I have upvoted your answer, also.fmw42

1 Answers

3
votes

cv2.COLOR_BGR2HSV means it expect BGR image as input and will return HSV image. It actually doesn't know if you pass exactly BGR or any other 3-channel format, but in your case you're trying to feed it 1-channel grayscale image and it is critical. You should convert grayscale back to BGR (opencv will just triple the gray channel) and then do BGR2HSV.

img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

But wait, why do you even need? Converting grayscale to HSV will give H and S channels full of zeros and V will be equals to gray channel what you already have.