- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 OpenCV 分水岭算法 ( https://docs.opencv.org/3.1.0/d3/db4/tutorial_py_watershed.html ),但稍作改动。文档中有这行代码:
ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
如果可能的话,我需要用 Otsu 的阈值法替换这个阈值法。我使用的大部分代码都来自 OpenCV 分水岭文档:
img = np.load('file.npy')
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations = 2)
sure_background = cv2.dilate(opening, kernel, iterations = 50)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_foreground = cv2.threshold(dist_transform, 0, dist_transform.max(), cv2.THRESH_BINARY + cv2.THRESH_OTSU)
最后一行导致错误:
/tmp/build/80754af9/opencv_1512687413662/work/modules/imgproc/src/thresh.cpp:1402: error: (-215) src.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) in function threshold
我知道在分水岭文档中,这一步没有 Otsu 的阈值,但我必须设置一个脚本以在非常多的图像上执行,对我来说很重要的是它不需要阈值为每个图像明确设置。
有没有办法使用 Otsu 的阈值在这个对象(cv2.distanceTransform 的结果)上运行这个方法(cv2.threshold)?
编辑
老实说,我没有在其他库中寻找类似的解决方案,但现在我在 scikit-image 库(http://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html)中找到了分水岭算法。它似乎在使用上没有那么复杂,可能会满足我的需要。但我问的可能对我(或其他人)以后有用,所以如果有人有解决方案,请分享它:)
编辑 2
当我通过添加此行对值进行规范化时:
dist_transform = cv2.normalize(dist_transform, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)
它成功了,但不幸的是,还有另一个问题。当我像这样运行 cv2.watershed 方法时:
ret, labels = cv2.connectedComponents(sure_foreground)
labels = labels + 1
labels[unknown == 255] = 0
labels = cv2.watershed(img, labels) # this line is wrong
我收到的错误消息是:
error: (-215) src.type() == (((0) & ((1 << 3) - 1)) + (((3)-1) << 3)) && dst.type() == (((4) & ((1 << 3) - 1)) + (((1)-1) << 3)) in function watershed
原因是我使用的图像是1 channel 数组,分水岭方法需要3 channel 数组(我在上面添加了加载图像)。有没有办法解决这个问题?数据类型正确(图像是 uint8,标签 - int32)。
最佳答案
您的问题在 documentation 中指定:
Currently, the Otsu’s method is implemented only for 8-bit images.
还有一个来自距离的变换:
dst – Output image with calculated distances. It is a 32-bit floating-point, single-channel image of the same size as src .
这意味着距离变换的输出与使用 Otsu 方法的阈值的输出不兼容......
可能的解决方案
您可以截断浮点值并将矩阵转换为 uint8 以便能够使用它。
np.uint8(dist_transform)
这可能会丢失一些数据,您必须小心负值和超过 255 的值...numpy 只会给您这样的值:
a = np.array([3.4, 2.7, 8.9, -1.2, 267])
np.uint8(a)
# result => array([ 3, 2, 8, 255, 11], dtype=uint8)
如您所见,您得到 -1.2 => 255 和 267 => 11 并且其他数字被截断...您可能需要考虑对数字进行四舍五入或将值标准化...。一切都取决于您的目标是什么以及你的距离变换看起来如何。
希望这对您有所帮助,并记得注意 src 和 dst 类型,这通常是 OpenCV 最常见的错误。
关于python - OpenCV 分水岭 + otsu with distanceTransform,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48382621/
我正在使用 Python 并尝试对图像进行 Otsu 阈值处理,但仅限于蒙版内部(是的,我有一个图像和一个蒙版图像)。这意味着图像上较少的像素将包含在用于计算 Otsu 阈值的直方图中。 我目前正在使
我想将 Otsu 阈值化应用于图像梯度(以去除噪声)。之后,我想计算梯度方向。不幸的是,当我这样做时,我只能得到 0 到 90 度之间的梯度方向。没有 Otsu 阈值,值介于 0 和 360 之间。
我正在使用 OpenCV 库中的 cvThresholding() 例程,使用 Otsu 的阈值方法执行二值化。有时这种方法会失败,这是可以理解的,因为 Otsu 为整个图像计算了一个阈值。为了改善结
我试图在使用 leptonica 处理后将图像保存为 jpeg。我将 python 与 ctypes 一起使用,我的代码是: import ctypes leptlib = "liblept.so"
我正在尝试实现多级 Otsu 阈值,更具体地说,我需要 3 个阈值/4 个类。 我知道关于 SO 的 2 个类似问题:#34856019 和 #22706742。问题是我没有得到好的结果:我已经阅读了
我正在尝试使用 OpenCV 分水岭算法 ( https://docs.opencv.org/3.1.0/d3/db4/tutorial_py_watershed.html ),但稍作改动。文档中有这
我正在使用图像比率和 Otsu 阈值在 2 个图像之间执行变化检测。代码的最后一行出错。 import cv2 import numpy as np image1 = cv2.imread( 'E:\
我正在 Android 平台上创建数独解决应用程序,但在处理图像时遇到了问题。我正在尝试使用 Sobel 过滤器使用 OpenCV 找到拼图的水平线,然后使用 Otsu 算法进行阈值处理: Mat k
我正在尝试对文档图像实现 Otsu 二值化技术,例如所示: 谁能告诉我如何在 MATLAB 中实现代码? 最佳答案 取自Otsu's method on Wikipedia I = imread('c
除了 OpenCV,我已经尝试环顾四周,但无法找到任何 Otsu 方法或中值滤波器在 Python 中的实现。这是我尝试过的仅有的两个 OpenCV 函数文档链接。 http://opencv.wil
这是我的例子。从左到右: 原始图片 灰度 + (3,3) 高斯模糊 Otsu 阈值化 + 反转像素 我想捕捉更多笔划的微弱部分。我知道 Otsu Thresholding 尝试在像素强度直方图的两个峰
我使用以下指令尝试了所有可能性: ret,thresh = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 但它总是给我同样的错误
我有图像,某些区域设置为 255 以不干扰感兴趣的区域。在做 Otsu 阈值时,这些区域会抵消阈值。 我找到了一个很好的answer如何做到这一点,但我的 python 实现很慢。考虑到我在 10,0
我将 Otsu 的二值化应用于一张图像并得到了这个结果 之后,我使用此代码在四个主要形状周围获取框: img = cv.imread('test_bin.jpg', 0) _, cnts, _ = c
我正在尝试使用 otsu 进行多阈值处理。我目前使用的方法实际上是通过最大化类间方差,我已经设法获得与 OpenCV 库给出的阈值相同的阈值。然而,这只是通过运行一次 otsu 方法。 关于如何进行多
我使用的是固定阈值,但事实证明它对我来说不太好。然后,有人告诉我大津阈值。我如何在我的代码中使用它?我读过它,但我不太了解。有人可以向我解释如何在 OpenCV 中使用 otsu 阈值吗? 现在这是我
为什么 Tesseract OCR 引擎使用全局阈值技术,例如 Otsu 二值化?局部阈值技术(例如 Sauvola、Niblack 等)在从图像中去除文本方面不是更有效吗? 最佳答案 Tessera
我尝试使用这两种方法,但自适应阈值似乎给出了更好的结果。我用过 cvSmooth( temp, dst,CV_GAUSSIAN,9,9, 0); 在原始图像上,只有我使用了阈值。 有什么我可以使用
我不需要阈值图像。我想要阈值。我在 OpenCV 中找到了这个。 cv::threshold( orig_img, thres_img, 0, 255, CV_THRESH_BINARY+CV_THR
如何像 Matlab 函数 graythresh 一样使用 OpenCV 仅获取 Otsu 阈值。 例如,如果我编写这段代码,我会像使用 Matlab 函数 im2bw 一样获得二进制图像: Mat
我是一名优秀的程序员,十分优秀!