Reputation: 440
In my ex-post I optimize the python iteration loop into numpy way.
Then I face next problem to convert it to binary image like this
def convertRed(rawimg):
blue = rawimg[:,:,0]
green = rawimg[:,:,1]
red = rawimg[:,:,2]
exg = 1.5*red-green-blue
processedimg = np.where(exg > 50, exg, 2)
ret2,th2 = cv2.threshold(processedimg,0,255,cv2.THRESH_OTSU) //error line
return processedimg
The error is here
error: (-215) src.type() == CV_8UC1 in function cv::threshold
How to solve this problem?
Upvotes: 0
Views: 3470
Reputation: 967
it is an error of "Data Type" ,
as Eliezer said,
when you multiply by 1.5 , the exg
matrix convert to float64
, which didn't work for cv2.threshold
which require uint8
data type ,
so , one of the solutions could be adding:
def convertRed(rawimg):
b = rawimg[:,:,0]
g = rawimg[:,:,1]
r = rawimg[:,:,2]
exg = 1.5*r-g-b;
processedimg = np.where(exg > 50, exg, 2)
processedimg = np.uint8(np.abs(processedimg));#abs to fix negative values,
ret2,th2 = cv2.threshold(processedimg,0,255,cv2.THRESH_OTSU) #error line
return processedimg
I used np.uint8()
after np.abs()
to avoid wrong result,(nigative to white ) in the converstion to uint8
data type.
Although , your very array processedimg
is positive, because of the np.where
statement applied before , but this practice is usually safer.
why it converts to float64
? because in python , when multiply any integer value with "float comma" it get converted to float ,
Like :
type(1.5*int(7))==float # true
another point is the usage of numpy functions instead of Opencv's, which is usually faster .
Upvotes: 1
Reputation: 2426
The cv2.threshold
function only accepts uint8 values, this means that you can only apply Otsu's algorithm if the pixel values in your image are between 0 and 255.
As you can see, when you multiply your values by 1.5
your image starts to present floating point values, making your image not suited for cv2.threshold
, hence your error message src.type() == CV_8UC1.
You can modify the following parts of your code:
processedimg = np.where(exg > 50, exg, 2)
processedimg = cv2.convertScaleAbs(processedimg)
ret2,th2 = cv2.threshold(processedimg,0,255,cv2.THRESH_OTSU) //error line
What we are doing here is using the OpenCV function cv2.convertScaleAbs
, you can see in the OpenCV Documentation:
cv2. convertScaleAbs
Scales, calculates absolute values, and converts the result to 8-bit.
Python: cv2.convertScaleAbs(src[, dst[, alpha[, beta]]]) → dst
Upvotes: 5