Есть ли способ удалить вертикальную яркую полосу на изображении в OpenCv? - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть изображение, как показано ниже: enter image description here

На этом изображении две яркие линии, проходящие через изображение, это то, что я хочу удалить / уменьшить.

Я использовал порог, чтобы можно было различить эти яркие полосы, который довольно хорошо выделяет области:

enter image description here

В настоящее время я пытаюсь уменьшить метод, при котором я пытаюсь просто уменьшить яркость пикселей, чтобы они не выделялись на изображении. Однако это приводит к странным результатам, и я не уверен, почему это так.

странные результаты: enter image description here

Из того, что я вижу, меняется значение пикселей, но оставляются нечетные результаты в конечном изображении.

До сих пор я использовал этот код для выполнения процесса:

img = cv2.imread('43.bmp')

h,s,v= cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))

ret1,th1 = cv2.threshold(v,240,255,cv2.THRESH_BINARY)

bright = np.where(th1, np.where((255-v) < 40, v-30,v),0)

th1_n = cv2.bitwise_not(th1) 
dark = np.where(th1_n,v,0)

result = bright + dark

mergeColour = cv2.cvtColor(cv2.merge([h,s,result]),cv2.COLOR_HSV2BGR)

cv2.imshow("frame", mergeColour.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()

Я не уверен точно, где я иду не так, или есть возможность лучшего способа получить то, что похоже на

Редактировать:

* То, что я хотел бы видеть, это то, что видимые линии становятся похожими по цвету с окружающими, поэтому может показаться, что они были удалены с изображения *

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Не уверен, на какой выход вы рассчитываете, но один из способов устранения неравномерного освещения состоит в том, чтобы взять копию изображения и смазать ее на большой области, чтобы удалить высокочастотные изменения и сохранить только низкочастотные, медленно меняющиеся области и вызвать это.фоновое освещение.Затем вычтите этот фон из исходного изображения.

Я просто делаю это с ImageMagick, который включен в большинство дистрибутивов Linux и доступен для macOS и Windows.Итак, просто в терминале:

convert input.gif \( +clone -blur 0x32 \) -compose difference -composite -auto-level result.jpg

enter image description here

Вы можете сделать то же самое в Python или C ++ с OpenCV, или PIL / Pillow или с CImgили с привязками ImageMagick Python.

По сути, обработка удаляет следующее в качестве фонового освещения:

enter image description here

1 голос
/ 03 апреля 2019

Этот ответ основан на предположении, что яркие пятна всегда выглядят как вертикальные линии. Он протестирован на этом образце изображения, и результаты довольно хорошие, но, безусловно, потребуется больше испытаний на других похожих изображениях. При этом я бы порекомендовал вам попытаться найти белые пятна на пороговом изображении, которые являются этими «пятнами», как вы уже разместили на втором последнем изображении. Вы можете получить местоположения или координаты, если хотите, транспонируя функцию np.findnonzero(thresholded_image). Затем выполните итерацию по списку и замените все пиксели исходного изображения с той же координатой, что и у iter, с пикселем до этого (x-1). Это результат:

import cv2
import numpy as np

img = cv2.imread('remove.png')
height,width = img.shape[:2]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray,225,255,cv2.THRESH_BINARY)

cds = np.transpose(np.nonzero(thresh))
for i in cds:
    if i[1] == 0:
        pass
    else:
        img[i[0],i[1]] = img[i[0], i[1]-1]


cv2.imshow("res", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Исходное изображение:

enter image description here

Thersholded изображение:

enter image description here

Результат изображения:

enter image description here

Надеюсь, это немного поможет или даст вам новую идею, которая может быть полезной. Ура!

EDIT:

Или еще один лучший подход: Используйте функцию cv2.inpaint() вместо повторения каждого пикселя:

import numpy as np
import cv2

img = cv2.imread('remove.png')
mask = cv2.imread('thresh.png',0)

dst = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)

cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

Результат:

enter image description here

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