Я отвечаю на ваш тег в соответствующем сообщении.Насколько я понимаю, вы и другая коллега работаете вместе над проектом по обнаружению родинок на коже?Потому что я думаю, что уже оказал помощь одному или, возможно, вам обоим по схожим вопросам и уже упомянул, что удаление волос является очень сложной и сложной задачей.Если вы удаляете волосы на изображении, вы теряете информацию и не можете заменить эту часть изображения (ни одна программа или алгоритм не может угадать, что находится под волосами - но это может дать оценку).То, что вы могли бы сделать, как я упоминал в других постах, и я думаю, что это будет лучший подход, это узнать о глубоких нейронных сетях и сделать свои собственные для удаления волос.Вы можете погуглить "удаление водяных знаков в глубокой нейронной сети" и посмотреть, что я имею в виду.При этом ваш код, по-видимому, не извлекает все области интереса (родинки), которые вы указали в примере изображения.Я сделал еще один пример того, как вы можете лучше извлечь родинки.В основном вам следует выполнить закрытие перед преобразованием в двоичный файл, и вы получите лучшие результаты.
Во второй части - удаление волос, если вы не хотите создавать нейронную сеть, я думаю, что альтернативное решение может быть, чтоВы вычисляете среднюю интенсивность пикселей в области, которая содержит моль.Затем выполните итерацию каждого пикселя и определите критерии того, насколько пиксель может отличаться от среднего значения.Волосы, кажется, представлены пикселями, которые темнее площади моль.Поэтому, когда вы найдете пиксель, замените его соседним пикселем, который не попадает под этот критерий.В примере я сделал простую логику, которая не будет работать с каждым изображением, но может служить примером.Чтобы сделать полностью работоспособное решение, вы должны сделать лучший, более сложный алгоритм, который, я думаю, займет довольно много времени.Надеюсь, это поможет немного!Ура!
import numpy as np
import cv2
from PIL import Image
# Read the image and perfrom an OTSU threshold
img = cv2.imread('skin2.png')
kernel = np.ones((15,15),np.uint8)
# Perform closing to remove hair and blur the image
closing = cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel, iterations = 2)
blur = cv2.blur(closing,(15,15))
# Binarize the image
gray = cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# Search for contours and select the biggest one
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
# Create a new mask for the result image
h, w = img.shape[:2]
mask = np.zeros((h, w), np.uint8)
# Draw the contour on the new mask and perform the bitwise operation
cv2.drawContours(mask, [cnt],-1, 255, -1)
res = cv2.bitwise_and(img, img, mask=mask)
# Calculate the mean color of the contour
mean = cv2.mean(res, mask = mask)
print(mean)
# Make some sort of criterion as the ratio hair vs. skin color varies
# thus makes it hard to unify the threshold.
# NOTE that this is only for example and it will not work with all images!!!
if mean[2] >182:
bp = mean[0]/100*35
gp = mean[1]/100*35
rp = mean[2]/100*35
elif 182 > mean[2] >160:
bp = mean[0]/100*30
gp = mean[1]/100*30
rp = mean[2]/100*30
elif 160>mean[2]>150:
bp = mean[0]/100*50
gp = mean[1]/100*50
rp = mean[2]/100*50
elif 150>mean[2]>120:
bp = mean[0]/100*60
gp = mean[1]/100*60
rp = mean[2]/100*60
else:
bp = mean[0]/100*53
gp = mean[1]/100*53
rp = mean[2]/100*53
# Write temporary image
cv2.imwrite('temp.png', res)
# Open the image with PIL and load it to RGB pixelpoints
mask2 = Image.open('temp.png')
pix = mask2.load()
x,y = mask2.size
# Itearate through the image and make some sort of logic to replace the pixels that
# differs from the mean of the image
# NOTE that this alghorithm is for example and it will not work with other images
for i in range(0,x):
for j in range(0,y):
if -1<pix[i,j][0]<bp or -1<pix[i,j][1]<gp or -1<pix[i,j][2]<rp:
try:
pix[i,j] = b,g,r
except:
pix[i,j] = (int(mean[0]),int(mean[1]),int(mean[2]))
else:
b,g,r = pix[i,j]
# Transform the image back to cv2 format and mask the result
res = np.array(mask2)
res = res[:,:,::-1].copy()
final = cv2.bitwise_and(res, res, mask=mask)
# Display the result
cv2.imshow('img', final)
cv2.waitKey(0)
cv2.destroyAllWindows()