I applied adaptive gaussian thresholding to my .tif image, but the black frame (contour) on the edges was created. Can't understand why and how to delete.
I would be very grateful for your help!
p.s. After cv2.threshold(img,127,255,cv2.THRESH_BINARY)
there is no frame.
This is my original image:
https://drive.google.com/file/d/1DfdmQQ9AS-U2SXtyJzU94oYsLLSUmV7N/view?usp=share_link
This is fragment of my image (colored) and after gaussian thresholding (white and black). The black countour on the edge of the image is clearly visible. enter image description here
My code:
img = cv2.imread(" My.tiff", 0)
th = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,115,2)
Tried this (found on the Stack overflow), but no results:
img = cv2.imread(file_path, 0)
rows, cols = img.shape
cv2.floodFill(img, None, seedPoint=(0, 0), newVal=255, loDiff=1, upDiff=1) # Fill the top left corner.
cv2.floodFill(img, None, seedPoint=(cols-1, 0), newVal=255, loDiff=1, upDiff=1) # Fill the top right corner.
cv2.floodFill(img, None, seedPoint=(0, rows-1), newVal=255, loDiff=1, upDiff=1) # Fill the bottop left corner.
cv2.floodFill(img, None, seedPoint=(cols-1, rows-1), newVal=255, loDiff=1, upDiff=1) # Fill the bottom right corner.
My image after adaptive gaussian thresholding (thresholding is ok..but why the black border was created and how to remove it, unfortunately, can't understand): enter image description here
The black edge is a result of the steep change in gray levels between the image data, and the white margins.
For fixing the issue, we may fill the margins with values that are closer to the pixels of the image, apply adaptiveThreshold
, and restore the margins.
Filling the margins with values that are closer to the pixels is not so simple.
Assuming the image is relatively homogeneous we may apply the following stages for covering the white margins:
After covering the margins, execute adaptiveThreshold
, and fill the margins with zeros.
Code sample:
import cv2
import numpy as np
img = cv2.imread('ndsi.tiff')
# Assume the margins are white, and there are very few white pixels in the other parts of the image.
# Create a mask with True where pixel are white and False otherwise.
mask = np.all(img != 255, axis=-1).astype(np.uint8)*255
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert to grayscale.
# Apply morphological closing for removing small white parts inside the image.
# Note for getting a better mask, we may find minAreaRect as suggested by Micka
#mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((5, 5), np.uint8))
#mask = cv2.erode(mask, np.ones((5, 5), np.uint8)) # Erode the mask, because there are too many artifacts
# Resize the image by a factor of 1.5 in each axis
resized_img = cv2.resize(img, (img.shape[1]*3//2, img.shape[0]*3//2))
# Blur with large kernel
resized_img_blurred = cv2.GaussianBlur(resized_img, (51, 51), 50)
# Crop the center that is the same size as the original image.
center_img_blurred = resized_img_blurred[(resized_img.shape[0] - img.shape[0])//2:(resized_img.shape[0] + img.shape[0])//2, (resized_img.shape[1] - img.shape[1])//2:(resized_img.shape[1] + img.shape[1])//2]
tmp_img = img.copy()
tmp_img[mask==0] = center_img_blurred[mask==0] # Replace white margins with resized blurred image.
# Apply the threshold on tmp_img
th = cv2.adaptiveThreshold(tmp_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
# Remove the margins from th
th[mask == 0] = 0
# Show images for testing:
cv2.imshow('mask', cv2.resize(mask, (1024, 1024)))
cv2.imshow('center_img_blurred', cv2.resize(center_img_blurred, (1024, 1024)))
cv2.imshow('tmp_img', cv2.resize(tmp_img, (1024, 1024)))
cv2.imshow('th', cv2.resize(th, (1024, 1024)))
cv2.waitKey()
cv2.destroyAllWindows()
cv2.imwrite('tmp_img.jpg', cv2.resize(tmp_img, (1024, 1024)))
cv2.imwrite('th.png', cv2.resize(th, (1024, 1024)))