使用numpy后Opencv Otsu Thresholding错误?

时间:2017-03-25 05:54:10

标签: python opencv numpy

In my ex-post我将python迭代循环优化为numpy方式。

然后我面临下一个将它转换为二进制图像的问题

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

错误在这里

  

错误:(-215)src.type()== CV_8UC1 in function cv :: threshold

如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

cv2.threshold函数只接受uint8值,这意味着如果图像中的像素值介于0到255之间,则只能应用Otsu算法。

正如您所看到的,当您将值乘以1.5时,您的图片会开始显示浮点值,使您的图片不适合cv2.threshold,因此您的错误消息 src.type ()== CV_8UC1

您可以修改代码的以下部分:

processedimg = np.where(exg > 50, exg, 2)
processedimg = cv2.convertScaleAbs(processedimg)
ret2,th2 = cv2.threshold(processedimg,0,255,cv2.THRESH_OTSU) //error line

我们在这里做的是使用OpenCV函数cv2.convertScaleAbs,您可以在OpenCV Documentation中看到:

cv2. convertScaleAbs
     

缩放,计算绝对值,并将结果转换为8位。

     

Python:cv2.convertScaleAbs(src [,dst [,   alpha [,beta]]])→dst

答案 1 :(得分:1)

这是“数据类型”的错误,

埃利泽说, 当您乘以1.5时,exg矩阵转换为float64,这对cv2.threshold无效,需要uint8数据类型,

所以,其中一个解决方案可能是添加:

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

我在np.uint8()之后使用了np.abs(),以避免在转换为uint8数据类型时出现错误结果(与白色相关)。

虽然,你的数组processedimg是正数,因为之前应用了np.where语句,但这种做法通常更安全。

为什么它转换为float64?因为在python中,当将任何整数值乘以“float comma”时,它会转换为float,

喜欢:

type(1.5*int(7))==float # true

另一点是使用numpy函数而不是Opencv,这通常更快。