mas内的Otsu阈值化

2024-09-26 22:53:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Python并尝试对图像进行Otsu阈值化,但仅限于遮罩内部(是的,我有一个图像和一个遮罩图像)。这意味着在计算Otsu阈值的直方图中将包含较少的图像像素。在

我目前使用的是cv2.threshold函数,没有掩码图像,不知道如何完成这种工作。在

ret, OtsuMat = cv2.threshold(GaborMat, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

因为这个函数也包含了遮罩之外的像素,我认为它会给出一个不太精确的阈值。在

以下是图像及其遮罩的示例:

https://drive.google.com/drive/folders/1p8JMhncJs19oOWO9RdkWuEADVGqE-gzQ?usp=sharing

希望有一个OpenCV或其他lib函数可以很容易地完成(也可以使用快速计算),但任何帮助都将不胜感激。在


Tags: 函数图像threshold阈值像素drive直方图cv2
1条回答
网友
1楼 · 发布于 2024-09-26 22:53:10

我尝试过使用skimage中的threshold_otsu()方法和Numpy掩码数组。我不知道是否有更快的方法,撇油通常都是非常优化的。如果其他人想取我的样本数据并尝试其他想法,请随时免费-尽管服务费为一票赞成;-)

#!/usr/bin/env python3

import cv2
import numpy as np
import numpy.ma as ma
from skimage.filters import threshold_otsu

# Set up some repeatable test data, 4 blocks 100x100 pixels each of random normal np.uint8s centred on 32, 64, 160,192
np.random.seed(42)
a=np.random.normal(size = (100,100), loc = 32,scale=10).astype(np.uint8)
b=np.random.normal(size = (100,100), loc = 64,scale=10).astype(np.uint8)
c=np.random.normal(size = (100,100), loc = 160,scale=10).astype(np.uint8)
d=np.random.normal(size = (100,100), loc = 192,scale=10).astype(np.uint8)
# Stack (concatenate) the 4 squares horizontally across the page
im = np.hstack((a,b,c,d))
# Next line is just for debug
cv2.imwrite('start.png',im)

这就给了我们这个:

enter image description here

^{pr2}$

测试数据的直方图如下所示,x轴为0..255

enter image description here


根据您自己的样本数据,我得到:

#!/usr/bin/env python3

import cv2
import numpy as np
import numpy.ma as ma
from skimage.filters import threshold_otsu

# Load images
im   = cv2.imread('eye.tif', cv2.IMREAD_UNCHANGED)
mask = cv2.imread('mask.tif', cv2.IMREAD_UNCHANGED)

# Calculate Otsu threshold on entire image
print(threshold_otsu(im))                       # prints 130

# Now do same for masked image
masked = ma.masked_array(im,mask>0)
print(threshold_otsu(masked.compressed())).     # prints 124

相关问题 更多 >

    热门问题