Как отбросить края изображения с помощью opencv? - PullRequest
0 голосов
/ 16 октября 2018

Я предварительно обрабатываю некоторые изображения, чтобы удалить фон из моей области интересов.Тем не менее, изображения на моей скамье имеют закругленные края из-за фокусировки камеры.Как я могу отбросить эти закругленные края и иметь возможность удалять только интересующий меня объект с изображения?Код ниже я могу удалить фон изображения, но он не работает правильно из-за краев вокруг.

import numpy as np
import cv2

#Read the image and perform threshold and get its height and weight
img = cv2.imread('IMD408.bmp')
h, w = img.shape[:2]

# Transform to gray colorspace and blur the image.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)

# Make a fake rectangle arround the image that will seperate the main contour.
cv2.rectangle(blur, (0,0), (w,h), (255,255,255), 10)

# Perform Otsu threshold.
_,thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

# Create a mask for bitwise operation
mask = np.zeros((h, w), np.uint8)

# Search for contours and iterate over contours. Make threshold for size to
# eliminate others.
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

for i in contours:
    cnt = cv2.contourArea(i)
    if 1000000 >cnt > 100000:
        cv2.drawContours(mask, [i],-1, 255, -1)


# Perform the bitwise operation.
res = cv2.bitwise_and(img, img, mask=mask)

# Display the result.
cv2.imwrite('IMD408.png', res)
cv2.imshow('img', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

входное изображение: enter image description here

Выход: enter image description here

Ошибка: enter image description here

1 Ответ

0 голосов
/ 16 октября 2018

Поскольку вы упомянули, что все изображения имеют одинаковый оттенок, то это должно хорошо сработать для них.Шаги, чтобы сделать баланс белого, который немного увеличит контраст.enter image description here

Получите оттенки серого.enter image description here

Порог для изображения в градациях серого.Значения меньше 127 установлены на 255 (белый).Это даст вам двоичное изображение, которое станет маской для исходного изображения.

enter image description here Примените маску

enter image description here

Возможно, вам придется поиграть с пороговым значением, если вы хотите улучшить результаты, вот ссылка для этого.Но это должно помочь вам начать.Я использую другую версию OpenCV по сравнению с тем, что вам, возможно, придется немного подправить код.

import cv2

def equaliseWhiteBalance(image):
    ''' Return equilised WB of an image '''
    wb = cv2.xphoto.createSimpleWB()                        #Create WB Object
    imgWB = wb.balanceWhite(img)                            #Balance White on image
    r,g,b = cv2.split(imgWB)                                #Get individual r,g,b channels
    r_equ  = cv2.equalizeHist(r)                            #Equalise RED channel
    g_equ  = cv2.equalizeHist(g)                            #Equalise GREEN channel
    b_equ  = cv2.equalizeHist(b)                            #Equalise BLUE channel
    img_equ_WB = cv2.merge([r_equ,g_equ,b_equ])             #Merge equalised channels
    return imgWB

#Read the image
img = cv2.imread('IMD408.bmp')
result = img.copy()

#Get whiteBalance of image
imgWB = equaliseWhiteBalance(img)

cv2.imshow('img', imgWB)
cv2.waitKey(0)

# Get gray image
gray = cv2.cvtColor(imgWB,cv2.COLOR_RGB2GRAY)
cv2.imshow('img', gray)
cv2.waitKey(0)

# Perform threshold
_, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
cv2.imshow('img', thresh)
cv2.waitKey(0)

# Apply mask
result[thresh!=0] = (255,255,255)

cv2.imshow('img', result)
cv2.waitKey(0)

Если все темные угловые виньетки имеют разные размеры на изображение, то я предлагаю искать центроид контуров надвоичное изображение (маска).Центроиды с «коротким» расстоянием до любого угла вашего изображения будут темными виньетками, поэтому их значение можно изменить с черного на белый.

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