OpenCV的threshold()二值化处理可以只在指定区域进行吗?

如题,现在我要对一个无人机影像(下图)进行OTSU二值化处理,理论上来说先转成灰度图像,再简单的调用cv2.threshold()就行了。

# 大津阈值分割,将土壤像素点变为0,植被像素点为1 
ret, th = cv2.threshold(gray, 0, 1, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # ret是获取到的最优阈值

img


带有黑边的遥感影像

但是可以看到,这个影像有个问题,它不是一个规则的区域。这样就使得这个影像周围存在大量的RGB值为(0,0,0)的黑边区域(转成灰度图像后这些区域值仍然是0)。

此时当我用threshold()的OTSU法去取二值化分割阈值时,因为OpenCV是根据影像的直方图操作的,而带有黑边的影像则存在大量的0值像素,使得直方图在0处出现一个错误的高峰(下图),进而导致OTSU法分割错误。

img


因为影像黑边产生的错误直方图,在0处出现了可怕的一个单峰

所以,请问该如何操作才能让threshold()只去做非黑边区域(非0区域)的二值化呢?也就是说直方图中能不能不包括黑边像素?

另外,我尝试过通过ArcGIS将黑边区域设置为noData,但是很遗憾当我导入到OpenCV打开后,貌似OpenCV还是会自动将这些noData空值区域又给它填上(0,0,0)的值。

本来看起来是个挺简单的问题,搞了很久都没搞定。到底该如何摆脱这些阴魂不散的黑边像素呢?

试一下中值滤波,去除黑色边际中可能含有的噪声干扰
然后用颜色过滤,先转换为HSV通道,然后设置阈值

已解决,手动实现一个OTSU算法即可。