c++ - 使用具有自适应阈值的掩码?

标签 c++ opencv

我正在使用 OpenCV-2.3 API 用 C++ 编写一个小程序。 我在使用非矩形掩码处理自适应阈值时遇到问题。

到目前为止,我正在对整个图像执行自适应阈值处理,然后进行掩蔽处理。我意识到,在我的例子中,这是一个错误,因为被屏蔽的像素将用于计算我感兴趣的像素的阈值(而我只是想从分析中排除前者)...... 然而,与 cv::norm 等函数不同,cv::adaptiveThreshold 似乎不支持明确的掩码。

您知道任何明显的解决方案或解决方法吗? 非常感谢你的建议, 昆汀

最佳答案

我已经编写了一些 Python(抱歉不是 C++)代码,这些代码将允许屏蔽自适应阈值。它不是很快,但它可以满足您的需求,您可以将它用作 C++ 代码的基础。它的工作原理如下:

  1. 将图像中的蒙版像素设置为零。
  2. 确定每个像素的卷积 block 内未屏蔽邻居的数量。
  3. 执行卷积,并根据 block 内未屏蔽邻居的数量对其进行平均。这会产生像素邻域 block 内的平均值。
  4. 阈值,通过将图像与平均邻域值进行比较,mean_conv
  5. 重新添加图像的屏蔽(非阈值)部分。

enter image description here

图像显示,初始图像, mask ,最终处理后的图像。

代码如下:

import cv
import numpy
from scipy import signal

def thresh(a, b, max_value, C):
    return max_value if a > b - C else 0

def mask(a,b):
    return a if b > 100 else 0

def unmask(a,b,c):
    return b if c > 100 else a

v_unmask = numpy.vectorize(unmask)
v_mask = numpy.vectorize(mask)
v_thresh = numpy.vectorize(thresh)

def block_size(size):
    block = numpy.ones((size, size), dtype='d')
    block[(size - 1 ) / 2, (size - 1 ) / 2] = 0
    return block

def get_number_neighbours(mask,block):
    '''returns number of unmasked neighbours of every element within block'''
    mask = mask / 255.0
    return signal.convolve2d(mask, block, mode='same', boundary='symm')

def masked_adaptive_threshold(image,mask,max_value,size,C):
    '''thresholds only using the unmasked elements'''
    block = block_size(size)
    conv = signal.convolve2d(image, block, mode='same', boundary='symm')
    mean_conv = conv / get_number_neighbours(mask,block)
    return v_thresh(image, mean_conv, max_value,C)

image = cv.LoadImageM("image.png", cv.CV_LOAD_IMAGE_GRAYSCALE)
mask = cv.LoadImageM("mask.png", cv.CV_LOAD_IMAGE_GRAYSCALE)

#change the images to numpy arrays
original_image = numpy.asarray(image)
mask = numpy.asarray(mask)
# Masks the image, by removing all masked pixels.
# Elements for mask > 100, will be processed
image = v_mask(original_image, mask)
# convolution parameters, size and C are crucial. See discussion in link below.
image = masked_adaptive_threshold(image,mask,max_value=255,size=7,C=5)
# puts the original masked off region of the image back
image = v_unmask(original_image, image, mask)
#change to suitable type for opencv
image = image.astype(numpy.uint8)
#convert back to cvmat
image = cv.fromarray(image)

cv.ShowImage('image', image)
#cv.SaveImage('final.png',image)
cv.WaitKey(0)

写完之后我发现this great link这对大量图像示例有很好的解释,我在上面的示例中使用了他们的文本图像。

注意。 scipy signal.convolve2d() 似乎不支持 Numpy 掩码,因此上述解决方法是必要的。

关于c++ - 使用具有自适应阈值的掩码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9842127/

相关文章:

c++ boost MPI & threading - 序列化错误 : Address not mapped

opencv - 阈值后温度为黑色

matlab - 一个类似于Matlab GrayThresh的OpenCV函数

python - 属性错误 : 'module' object has no attribute 'face' error even after installing opencv-contrib

c++ - C++中构造函数的返回类型

c++ - 使用未初始化的成员复制结构

c++ - 编译器会优化这个还是我需要分配?

c - OPENCV:我想在循环中绘制基本形状,每次绘制新形状时删除旧形状

JavaCV - 前缀 'cv' 和不前缀有什么区别

c++ - 如何在c中进行基于事件的串口读取?