Based on this answer's algorithm I have written my code which is working as intended.
Here's a breakdown of the coding steps:
Otsu's thresholding is applied to the grayscale
cv2.threshold() with the
cv2.THRESH_BINARY + cv2.THRESH_OTSU flag to obtain
Erosion is performed on
cv2.erode() with a square kernel to obtain
The threshold distance
K is defined.
You then compare to 0 for pixels where
image2 is larger than 0. So you can combine the result of the two full-image comparisons with the logical
and(&) operator, and use the result to index into the output image.
final image is displayed using
Note that a square region with side
2*K is used instead of a circular mask in this implementation.
The choice between a circular or square area can be adjusted by modifying the mask variable in the code.
Feel free to adjust the threshold distance
K and experiment with different shapes and sizes of the neighborhood mask to suit your specific requirements.
import numpy as np
# Load the image
image1 = cv2.imread('orange.jpg', cv2.IMREAD_GRAYSCALE)
# Otsu's thresholding
_, image2 = cv2.threshold(image1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
kernel = np.ones((5, 5), np.uint8)
image3 = cv2.erode(image2, kernel, iterations=1)
# Define the threshold distance K
K = 2
# Iterate over image1 pixels and generate the final image
final_image = np.copy(image1)
final_image[(cv2.blur(image3,[2*K+1, 2*K+1]) > 0) & (image2 > 0)] = 0
# Display the original and final image
cv2.imshow('Original image', image1)
cv2.imshow('Final Image', final_image)