John
John

Reputation: 207

How to decide on the kernel to use for dilations (OpenCV/Python)?

I'm very new to OpenCV and recently, I'm trying to compare two images of rails, one with a train and one without. After the comparison, I apply a threshold, and there are some 'holes' in the white regions which I do not want. Currently, I am using dilation with 4 iterations and kernel set to "None", which defaults to a 3x3 by my understanding.

How do I decide what sort of kernel to use so that the dilation does a better job at making the white region continuous? Would also be nice if I could remove the small white blobs in the background. Here is the code:

resized = imutils.resize(img2, width=1050)
resized2 = imutils.resize(img3, width=1050)
grayA = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(resized2, cv2.COLOR_BGR2GRAY)
grayA = cv2.GaussianBlur(grayA,(7,7),0)
grayB = cv2.GaussianBlur(grayB,(7,7),0)
frameDelta = cv2.absdiff(grayA, grayB)
thresh = cv2.threshold(frameDelta, 20, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=4)

enter image description here

Complete beginner in this, so even general tips/advice to improve these comparisons would be vastly appreciated!

Upvotes: 5

Views: 7859

Answers (1)

fmw42
fmw42

Reputation: 53164

Perhaps this will give you some idea about morphology in Python/OpenCV. First I use a square "open" kernel about the size of the small white spots to remove them. Then I use a horizontal rectangle "close" kernel about the size of the black gap to fill it. "Open" removes white regions (or fills black gaps) and close removes black regions (or fills white gaps)

Input:

enter image description here

import cv2
import numpy as np

# read image as grayscale
img = cv2.imread('blob3.png', cv2.IMREAD_GRAYSCALE)

# threshold to binary
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY)[1]

# apply morphology open with square kernel to remove small white spots
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19,19))
morph1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

# apply morphology close with horizontal rectangle kernel to fill horizontal gap
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (101,1))
morph2 = cv2.morphologyEx(morph1, cv2.MORPH_CLOSE, kernel)

# write results
cv2.imwrite("blob3_morph1.png", morph1)
cv2.imwrite("blob3_morph2.png", morph2)

# show results
cv2.imshow("thresh", thresh)
cv2.imshow("morph1", morph1)
cv2.imshow("morph2", morph2)
cv2.waitKey(0)

Morphology Square Open:

enter image description here

Morphology Rectangle Close:

enter image description here

Alternate Morphology Square Close:

enter image description here

Upvotes: 7

Related Questions