OpenCV与特定于Python的筛选器不同

OpenCV与特定于Python的筛选器不同,python,opencv,Python,Opencv,我正在尝试用Python和OpenCV制作一个Kirsch过滤器。我正努力做到这一点 问题是它给了我一个与Matlab完全不同的结果 预期产量 Python和OpenCV给了我一个完全黑色的图像 我哪里做错了 以下是我编写的代码: 导入cv2 将numpy作为np导入 np.set\u打印选项(阈值=np.nan) resim=cv2.imread('filter.jpg') resim=cv2.cvt颜色(resim,cv2.COLOR\u RGB2GRAY) h1=np.array([[5

我正在尝试用Python和OpenCV制作一个Kirsch过滤器。我正努力做到这一点

问题是它给了我一个与Matlab完全不同的结果

预期产量

Python和OpenCV给了我一个完全黑色的图像

我哪里做错了

以下是我编写的代码:

导入cv2
将numpy作为np导入
np.set\u打印选项(阈值=np.nan)
resim=cv2.imread('filter.jpg')
resim=cv2.cvt颜色(resim,cv2.COLOR\u RGB2GRAY)
h1=np.array([[5,-3,-3],-5,0,-3],[5,-3,-3]],dtype=np.float32)/15
h2=np.array([[-3,-3,5],-3,0,5],-3,-3,5]],dtype=np.float32)/15
h3=np.array([[-3,-3],[5,0,-3],[5,5,-3]],dtype=np.float32)/15
h4=np.array([[-3,5,5],-3,0,5],-3,-3]],dtype=np.float32)/15
h5=np.array([[-3,-3],-3,0,-3],[5,5,5]],dtype=np.float32)/15
h6=np.array([[5,5,5],-3,0,-3],-3,-3]],dtype=np.float32)/15
h7=np.array([[-3,-3,-3],-3,0,5],-3,5,5]],dtype=np.float32)/15
h8=np.array([[5,5,-3],[5,0,-3],-3,-3]],dtype=np.float32)/15
打印(h1)
新的\u img1=cv2.filter2D(resim,-1,h1)
new_img2=cv2.filter2D(resim,-1,h2)
new_img3=cv2.filter2D(resim,-1,h3)
new_img4=cv2.filter2D(resim,-1,h4)
new_img5=cv2.filter2D(resim,-1,h5)
new_img6=cv2.filter2D(resim,-1,h6
new_img7=cv2.filter2D(resim,-1,h7)
new_img8=cv2.filter2D(resim,-1,h8)
cv2.imshow(“彩色图像”,新img1)
cv2.等待键(0)
cv2.destroyAllWindows()

第6行出现错误,您的值为-5,而不是5

h1 = np.array([[5, -3, -3], [5, 0, -3], [5, -3, -3]], dtype=np.float32)/ 15

除了注意到的输入错误,代码没有使用所有8个Kirsch子过滤器的最大值。而且,它也没有对结果进行阈值设置和反转

这应该可以做到:

#!/usr/bin/python

import  cv2
import  numpy

KIRSCH_K1   = numpy.array([[ 5, -3, -3], [ 5,  0, -3], [ 5, -3, -3]], dtype=numpy.float32) / 15
KIRSCH_K2   = numpy.array([[-3, -3,  5], [-3,  0,  5], [-3, -3,  5]], dtype=numpy.float32) / 15
KIRSCH_K3   = numpy.array([[-3, -3, -3], [ 5,  0, -3], [ 5,  5, -3]], dtype=numpy.float32) / 15
KIRSCH_K4   = numpy.array([[-3,  5,  5], [-3,  0,  5], [-3, -3, -3]], dtype=numpy.float32) / 15
KIRSCH_K5   = numpy.array([[-3, -3, -3], [-3,  0, -3], [ 5,  5,  5]], dtype=numpy.float32) / 15
KIRSCH_K6   = numpy.array([[ 5,  5,  5], [-3,  0, -3], [-3, -3, -3]], dtype=numpy.float32) / 15
KIRSCH_K7   = numpy.array([[-3, -3, -3], [-3,  0,  5], [-3,  5,  5]], dtype=numpy.float32) / 15
KIRSCH_K8   = numpy.array([[ 5,  5, -3], [ 5,  0, -3], [-3, -3, -3]], dtype=numpy.float32) / 15

def kirsch_filter(img) :
    """ Return a gray-scale image that's been Kirsch edge filtered. """
    if  img.ndim > 2 :
        img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    fimg    = numpy.maximum(cv2.filter2D(img, cv2.CV_8U, KIRSCH_K1),
              numpy.maximum(cv2.filter2D(img, cv2.CV_8U, KIRSCH_K2),
              numpy.maximum(cv2.filter2D(img, cv2.CV_8U, KIRSCH_K3),
              numpy.maximum(cv2.filter2D(img, cv2.CV_8U, KIRSCH_K4),
              numpy.maximum(cv2.filter2D(img, cv2.CV_8U, KIRSCH_K5),
              numpy.maximum(cv2.filter2D(img, cv2.CV_8U, KIRSCH_K6),
              numpy.maximum(cv2.filter2D(img, cv2.CV_8U, KIRSCH_K7),
                            cv2.filter2D(img, cv2.CV_8U, KIRSCH_K8),
                           )))))))
    return(fimg)


def threshold(img, sig = None) :
    """ Threshold a gray image in a way that usually makes sense. """
    if  img.ndim > 2 :
        img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    med     = numpy.median(img)
    if  sig is None :
        sig = 0.0       # note: sig can be negative. Another way: Use the %'th percentile-ish pixel.
    co      = int(min(255, max(0, (1.0 + sig) * med)))
    return(cv2.threshold(img, co, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C)[1])



if  __name__ == '__main__' :
    import  os
    import  sys

    fn      = "x.png"
    if  len(sys.argv) > 1 :
        fn  = sys.argv.pop(1)
    sig     = None
    if  len(sys.argv) > 1 :
        sig = float(sys.argv.pop(1))

    img     = cv2.imread(fn)

    kimg    = kirsch_filter(img)    # make each pixel the maximum edginess value
    timg    = threshold(kimg, sig)  # make the edges stand out
    timg    = 255 - timg            # invert the image to make the edges white

    cv2.imshow('%s kirsch filtered' % os.path.basename(fn), timg)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

# eof

其他答案中存在严重问题:

  • 它们不使用浮点值进行计算,因此某些边框可能会丢失。请参阅:。在下一幅图像中,在CV_8U图像和CV_64F图像上直接应用了过滤器,很明显,第一幅图像中的边框丢失了

  • 之后他们不会将结果正常化
这一实施基于:

这些是应用于维基百科样本图像的结果。如果你比较这两个结果,你会发现它们非常相似:

  • 这一实施:

  • 年维基百科的结果

最后,您可以这样使用此实现:

fg = cv2.imread("Boxfilter_pavilion_original.jpg")
fg_rgb = cv2.cvtColor(fg, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(fg_rgb, cv2.COLOR_RGB2GRAY)    
bin = kirsch_filter(gray)
# show results 
plt.imshow(bin, interpolation='none', cmap='gray')
plt.xticks([]), plt.yticks([])
plt.show()

有点太短,不能作为答案。你应该解释原因并更好地识别代码片段。因为它现在是一个注释,而不是答案。
fg = cv2.imread("Boxfilter_pavilion_original.jpg")
fg_rgb = cv2.cvtColor(fg, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(fg_rgb, cv2.COLOR_RGB2GRAY)    
bin = kirsch_filter(gray)
# show results 
plt.imshow(bin, interpolation='none', cmap='gray')
plt.xticks([]), plt.yticks([])
plt.show()