Как эффективно обнаружить тени на стати c изображении? - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь выполнить вычитание фона для изображений c, используя Python и OpenCV, вот мой текущий метод вычитания фона:

def subtract_background(image: np.ndarray):
img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(img, cmap='Greys_r')
plt.show(block=True)

imgNoShadows = remove_shadows(img)

gsImg = cv2.cvtColor(imgNoShadows, cv2.COLOR_RGB2GRAY)
# plt.imshow(gsImg, cmap='Greys_r')

blur = cv2.GaussianBlur(gsImg, (55, 55), 0)
plt.imshow(blur, cmap='Greys_r')
plt.show(block=True)

retOtsu, imgOtsu = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
plt.imshow(imgOtsu, cmap='Greys_r')
plt.show(block=True)

tempKernel = np.ones((10, 10), np.uint8)
closedImg = cv2.morphologyEx(imgOtsu, cv2.MORPH_CLOSE, tempKernel)
plt.imshow(closedImg, cmap='Greys_r')

# contours
contours, hierarchy = cv2.findContours(closedImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(len(contours))

# creating a mask image for background subtraction using the contour
x, y = closedImg.shape

black_img = np.empty([x, y, 3], dtype=np.uint8)
black_img.fill(0)
plt.imshow(black_img, cmap='Greys_r')
plt.show(block=True)

index = find_contour(contours, img)
cnt = contours[index]
mask = cv2.drawContours(black_img, [cnt], 0, (255, 255, 255), -1)
plt.imshow(mask)
plt.show(block=True)

return mask

maskedImg = cv2.bitwise_and(img, mask)
whitePx = [255, 255, 255]
blackPx = [0, 0, 0]

finalImg = maskedImg
h, w, channels = finalImg.shape
for x in range(0, w):
    for y in range(0, h):
       channels_xy = finalImg[y, x]
    if all(channels_xy == blackPx):
        finalImg[y, x] = whitePx

plt.imshow(finalImg)
plt.show(block=True)
return finalImg

Это, кажется, обнаруживает большую часть фона и вычитает это правильно, но тени оказались трудными, и они продолжают проходить через все пороги и контуры. Я пытался использовать cv2.createBackgroundSubtractorMOG2(), но он возвращает полностью черное изображение. Этот метод, кажется, работает только для кадров в видео, так как я уверен, что MOG2 узнает, какая тень основана на прошлых кадрах. Я пробовал это для обнаружения теней для моих изображений c:

def remove_shadows(image: np.ndarray) -> np.ndarray:
rgbPlanes = cv2.split(image)
resultPlanes = []
resultNormalPlanes = []
for plane in rgbPlanes:
    dilatedImg = cv2.dilate(plane, np.ones((7, 7), np.uint8))
    bgImg = cv2.medianBlur(dilatedImg, 21)
    diffImg = 255 - cv2.absdiff(plane, bgImg)
    normImg = cv2.normalize(diffImg, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)
    resultPlanes.append(diffImg)
    resultNormalPlanes.append(normImg)
result = cv2.merge(resultPlanes)
resultNormal = cv2.merge(resultNormalPlanes)
plt.imshow(result)
plt.show(block=True)
plt.imshow(resultNormal)
plt.show(block=True)
return resultNormal

Этот метод фактически делает обнаружение фона менее эффективным. Существует ли эффективное решение для обнаружения теней изображения c?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...