简体   繁体   中英

My erode() function doesn't produce same output as openCV's erode function

So i've used a border for the pixels that are 'outside' the image so the kernel can use the border's pixels to get a minimum. I've no idea why my function would produce a different output to that of the inbuilt function - I've inspected both outputs carefully (writing to an image and zooming in) and looking very carefully I can't notice a difference in pixels!

import cv2 import numpy as np

img = cv2.imread('lena.png',cv2.IMREAD_GRAYSCALE)

reflect = cv2.copyMakeBorder(img,3,3,3,3,cv2.BORDER_REFLECT)

cv2.imshow('img', reflect)
cv2.waitKey(0)

imgEroded = np.zeros((512+6,512+6,3), np.uint8)

for i in range(0,reflect.shape[0]):
    for j in range(0,reflect.shape[1]):
        n = np.matrix(reflect[i-3:i+2, j-3:j+2])
        if n.size > 0:  
            imgEroded[i][j] = n.min()

imgEroded = imgEroded[3:512+3, 3:512+3]

kernel = np.ones((5,5),np.uint8)
erode = cv2.erode(img,kernel)
# print  erode.shape[:2]
cv2.imshow('erosionCorrect',erode)
cv2.imshow('erosion',imgEroded)

cv2.imwrite('myOutput.png',imgEroded)
cv2.imwrite('correct.png',erode)


print(np.array_equal(erode, imgEroded))

# cv2.imshow('real',erode)
cv2.waitKey(0)

Your code is fine except two small issues:

First, imgEroded is a three-channel image while erode is a single channel image (you read img as grayscale), so just simply create a single-channel imgEroded .

Second, you're one pixel off in your indexing for your n matrix. If you index an array like arr[i-3:i+2] this means starting at index i-3 and going up to i+2 , which means you're indexing i-3, i-2, i-1, i, i+1 . This has size five, which is correct, but the center isn't i , it's i-1 . So you should be indexing i-2:i+3 . Same with j of course. This also means you actually only need to copyMakeBorder() two pixels wide and not three, but that's not really a big deal.

With these two changes:

imgEroded = np.zeros((512+6,512+6), np.uint8)

and

n = np.matrix(reflect[i-2:i+3, j-2:j+3])

on the corresponding lines, print(np.array_equal(erode, imgEroded)) prints True .

FYI to help debug images that look similar, I find printing the numpy image array to be super helpful; that's how I spotted both errors. The 1-ch vs 3-ch is immediately obvious, but then after correcting that I simply noticed that the second matrix was basically the same but shifted a pixel in each direction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM