Как отделить фотоделанную часть от остальной части изображения, если дано исходное изображение? - PullRequest
1 голос
/ 14 апреля 2019

Я работаю над проектом по обнаружению сплайсированных (фотошопированных) изображений и хочу, чтобы на границах поддельных областей были исправления размером 128x128. У меня есть подлинное фоновое изображение и поддельное.

Если я просто нахожу разницу в значениях пикселей и применяю пороговое значение для получения двоичного изображения, я получаю много шума (маленькие черные пятна в белой части и наоборот), которые не удаляются эффективно cv2.medianBlur() , Я предполагаю, что это из-за разных коэффициентов сжатия изображений до и после сращивания. Кроме того, некоторые пиксели в склеенной части аналогичны соответствующим пикселям в аутентификации. изображение.

Таким образом, я заменяю обычную функцию cv2.threshold(), которая добавляет значения 4-соединенных соседей пикселя и сравнивает их с пороговым значением.

Это моя пороговая функция:

def threshold(image,thresh):
    b,g,r= cv2.split(image)
    res=np.zeros(b.shape,dtype=np.uint8)

    #Not considering boundary pixels for the binary image
    for i in range(1,b.shape[0]-1):
        for j in range(1,b.shape[1]-1):
            sumb = b[i][j] + b[i+1][j] + b[i-1][j] + b[i][j+1] + b[i][j-1] 
            sumg = g[i][j] + g[i+1][j] + g[i-1][j] + g[i][j+1] + g[i][j-1] 
            sumr = r[i][j] + r[i+1][j] + r[i-1][j] + r[i][j+1] + r[i][j-1] 

            res[i][j]=255 if sumb<=5*thresh or sumg<=5*thresh or sumr<=5*thresh else 0

    res=res[1:-1,1:-1]
    res=cv2.copyMakeBorder(res,1,1,1,1,cv2.BORDER_REFLECT_101)
    return res

Это дает лучшие результаты, но не так хорошо, как ожидалось.

Например, это подлинное изображение:

original

Это склеенное изображение:

spliced

Это пороговое изображение (я обнаружил, что thresh=2 было оптимальным значением):

thresholded

Я попытался удалить мелкие компоненты, удалив компоненты с несколькими белыми пикселями, используя connectedComponentsWithStats().

Это границы после удаления мелких подключенных компонентов:

borders

в то время как ожидаемое изображение:

expected

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

Как я могу получить лучшие результаты, чем этот?

Кроме того, возможно ли оптимизировать мою функцию threshold? Сейчас обработка одного изображения занимает не менее 2 секунд!

1 Ответ

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

[У меня не установлено OpenCV на моем компьютере прямо сейчас, поэтому вместо этого посмотрел ваши изображения в MATLAB. Код Python ниже не проверен.]

Поскольку ваши изображения идентичны, за исключением случаев, когда были сделаны целенаправленные изменения (масштабирование или переводы не принимаются во внимание), можно просто вычесть два изображения и посмотреть на разницу:

res = cv2.absdiff(image,thresh)

Если вы отобразите это (с некоторым контрастным натяжением), вы увидите:

absolute difference between the two images

Как вы можете видеть, по крайней мере один из каналов имеет сильную разницу в «сращенной» области, за ее пределами есть несколько очень легких точек, вызванных сжатием с потерями.

Давайте возьмем максимум по R, G, B для каждого пикселя:

res = np.amax(res, axis=2)   # (I think OpenCV stores the channels in the 3rd dimension?)

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

res = res > 15

Наконец, примените ваш cv2.medianBlur(), чтобы удалить последние биты шума. Вы также можете попробовать применить GaussianBlur() до порога.

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