首页 > 解决方案 > 如何将 OpenCV 阈值方法应用于 Skimage 方法输出的形态图像?

问题描述

我使用的代码根据定义的阈值从图像中删除大对象。

我正在使用的代码在skimage模块的形态操作之后保存文件:

from skimage import measure, morphology

# EDIT: added blobs_labels calculation
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]  # ensure binary        
blobs = img > img.mean()
blobs_labels = measure.label(blobs, background=1)
constant = 200

b = morphology.remove_small_objects(blobs_labels, constant)
# save the the pre-version which is the image is labelled with colors
plt.imsave('pre_version.png', b)
# read the pre-version
img = cv2.imread('pre_version.png', 0)
img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

现在我将直接应用阈值方法 - 不保存中间的图像 - 到形态图像输出(b):

b = morphology.remove_small_objects(blobs_labels, constant)
img = cv2.threshold(b, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

但是,如果我按上述方式更改代码,则会收到以下错误:

错误:OpenCV(4.1.2) C:\projects\opencv-python\opencv\modules\imgproc\src\thresh.cpp:1527:

错误:(-215:断言失败)src.type() == CV_8UC1 in function 'cv::threshold'

我的问题是,为什么我不能直接将阈值方法应用于形态输出?

标签: pythonopencvscikit-image

解决方案


您没有告诉我们有关blobs_labels的任何信息,因此很难确定,但问题可能出在图像的数据类型上。skimage.morphology.remove_small_objects保持原来的数据类型,所以如果是cv2不想要的类型,就会报错。转换为 uint8 解决了我的问题。

import cv2
import skimage.morphology

blobs_labels = skimage.data.binary_blobs()
constant = 16
b = skimage.morphology.remove_small_objects(blobs_labels, constant)
b = b.astype('uint8')
img = cv2.threshold(b, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

您的图像读取代码工作可能是因为 cv2 正在将数据转换为它可以使用的类型。


推荐阅读