图像侵蚀手动实现不做任何事情 Python

Posted

技术标签:

【中文标题】图像侵蚀手动实现不做任何事情 Python【英文标题】:Image Erosion manual implementation not doing anything Python 【发布时间】:2020-07-26 09:17:22 【问题描述】:

Testing image

我编写了一个 Python 脚本,该脚本使用随附的测试图像对图像手动执行 侵蚀形态学操作,但是当我同时显示原始图像和更改后的图像时,即使最后一个看起来仍然相同认为它应该被侵蚀。

我有 3 个函数,我的 Main 函数、RGB 到灰度转换函数和 Erosion 函数。

import cv2
import math
import numpy as np
from PIL import Image, ImageFilter

def main():
    #Read image
    img = cv2.imread('pattern04.bmp')
    #Convert it to gray scale (One color channel)
    imgg = gray(img)
    #Manually create my structuring element (kernel)
    se = [[0,1,0],
          [1,1,1],
          [0,1,0]]
    #Call morphological operation function
    erode(imgg,se)


def erode(im,se):
    rows,columns = im.shape[0], im.shape[1]
    #Initialize counters (Just to keep track)
    fit = 0
    hit = 0
    miss = 0

    #Create a copy of the image to modified it´s pixel values
    ero = im
    #Specify kernel size (w*w)
    w = 3

    #
    for i in range(rows-w-1):
        for j in range(columns-w-1):
            #Get a region (crop) of the image equal to kernel size
            crop = im[i:w+i,j:w+j]
            #Convert region of image to an array
            img = np.array(crop)

            #Get center
            a = math.floor(w/2)
            b = math.floor(w/2)
            
            #Initialize counters 
            matches = 0
            blacks = 0

            #Count number of black pixels (0) and value matches between the two matrix
            for x in range(w):
                for y in range(w):
                    #Count number of black pixels (0)
                    if(img[x][y] == 0):
                        blacks = blacks+1
                        #Count number of matching pixel values between the two matrix   
                        if (img[x][y] == se[x][y]):         
                            matches = matches+1

            #Test if structuring element fit crop image pixels
            #If fit it does nothing because center pixel is already black
            if(matches > 0):
                if(matches == blacks):
                    #Touch
                    fit = fit + 1
                    pass
                #Test if structuring element hit crop image pixels
                #If hit change ero center pixel to black
                elif(matches < blacks):
                    #Hit
                    hit = hit+1
                    ##PROBABLE ERROR IN HERE##
                    ero[a][b] = 0
            #If no pixel match just pass
            else:
                #Miss
                miss=miss+1
                pass

    #Print the number of fits, hits, and misses
    print(str(fit) + '\n' + str(hit) + '\n' + str(miss))

    #Show original gray image and eroded image
    cv2.imshow('Original', im)
    cv2.imshow('Erosion', ero)
    cv2.waitKey(0)


#Function to convert RGB image (3 color channels) to Gray scale (1 color channel)
def gray(img):
    channel = img.shape[2]
    if (channel > 1):
        g_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        return(g_img)
    else:
        return(img)

if __name__ == "__main__":
    main()

我的代码所做的是获取测试图像,将其转换为灰度(只有一个颜色通道)并传递给 Erode 函数。我创建了一个结构元素来使用它是一个矩阵,它将在这个过程中作为我的内核。 我裁剪灰度图像的一个区域并将其转换为与我的结构元素(内核)大小相同的矩阵,然后,我“重叠”这两个矩阵以查看在一个特定坐标中是否有任何像素矩阵在第二个矩阵的同一坐标中具有相同的值。 我创建了一个名为 ero 的灰度图像副本,我将对其进行修改。

有 3 种情况。

1) 如果所有黑色像素都匹配,则匹配且不执行任何操作

2) 如果一个或多个(但不是全部)黑色像素匹配它 应该将 ero 的中心像素的颜色更改为黑色

3) 如果没有像素匹配,它什么也不做。

我使用前两个 for 循环来裁剪图像的不同区域以穿过整个区域,接下来的两个 for 循环用于迭代裁剪图像和内核的每个像素并检查像素是否匹配。 **我认为错误在标记为的行中

##此处可能出现错误##

因为是指定改变中心像素颜色的那个。**(不会改变)

如果我运行代码,两个图像(灰度原始图像和 ero 图像)看起来都一样。 对错误可能是什么有任何想法?

【问题讨论】:

尝试使用ero = np.copy(im)创建您的副本 【参考方案1】:

因为w 永远不会改变,所以ab 也总是相同的。因此,当您使用 ero[a][b] = 0 写入输出时,您总是将相同的像素设置为 0。相反,将像素设置在窗口的中心:

ero[i+a][j+b] = 0

此外,ero = im 导致两个变量引用同一个数组,修改一个将修改另一个。创建副本as Mark suggests in a comment:

ero = np.copy(im)

代码可能有更多问题,我没有尝试运行它。它当然可以使用一些向量化:xy 上的循环可以替换为两个向量化的 NumPy 操作:

blacks = np.coount_nonzero(img == 0)
matches = np.coount_nonzero((img == 0) & (se == 0))

但是,假设图像和结构元素的值都只有 0 和 255,腐蚀操作应该简单地写成

ero[i+a][j+b] = np.all(img[se==255]) * 255

也就是说,只有设置了 SE 命中的所有像素后,才会设置输出。这里的复杂性来自于使用值为 0 和 255 的数值数组而不是逻辑数组,这将进一步简化表达式。

膨胀会将all 替换为any

【讨论】:

但是如果我用循环替换 x 和 y 以用矢量化操作替换它们,我将如何定义我的 x 和 y 值? 'ero[i+a][j+b] = np.all(img[se==255]) * 255' 应该进入 if 语句 'if(matches @Charles:对不起,我忘了删除那里的 x 和 y。固定的。另一个语句适用于所有像素,不需要 ifs。也不需要通过复制输入来初始化输出图像,您只需创建一个正确大小的未初始化图像。这句话的意思是“只有当 SE 覆盖的所有像素都是前景像素时,才会设置输出。”

以上是关于图像侵蚀手动实现不做任何事情 Python的主要内容,如果未能解决你的问题,请参考以下文章

下拉框更改时提交表单 - 不做任何事情

ListView onItemClickListener 不做任何事情

cordova-plugin-purchase:即使在调用命令之后,iOS 也不做任何事情

WebSocketSession.send 不做任何事情

TabControl.VerticalAlignment = 拉伸不做任何事情

npm update 不做任何事情