вычитание фона или изменение цвета фона контура, обнаруженного в Python - PullRequest
0 голосов
/ 04 сентября 2018

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

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

Я попытался извлечь черный фон и изменить его на желтый

Пожалуйста, найдите мой код ниже:

import cv2
import numpy as np
mask_color= (0.0,0.0,1.0)

#reading the image
img= cv2.imread('notused.jpg')

#convering the image into grayscale
gray_image= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#applying threshold
ret,thresh= cv2.threshold(gray_image,70,255,cv2.THRESH_BINARY)

#finding contours on the original image
_, contours,hierarchy =cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

#creating a mask as of the image size which is a black image
mask= np.zeros(img.shape[:2],np.uint8)

#inverted to get a white image
maskinv=cv2.bitwise_not(mask)

#drawn contours on the white image
mask_contours=cv2.drawContours(maskinv,contours,0,0,-3)

#converted to 3 channels
mask_stack= np.dstack([mask_contours]*3)


#to get only the background and remove all the contours 
img1=cv2.bitwise_xor(img,img,mask)

#changing every pixel of the background image to yellow
for y in range(img1.shape[0]-1): #row values
    for x in range(img1.shape[1]-1): #column values
        img1[y,x]=(0,255,255)

Затем я воспользовался этим: Как удалить фон с этого вида изображения?

Это должно было смешать исходное изображение с созданным фоном, но, кажется, не работает и выдает ошибку

mask_stack= mask_contours.astype('float32')/255.0
img1=img1.astype('float32')/255.0

masked= (mask_stack *img1)+((1-mask_stack)*mask_color)
masked=(masked*255).astype('uint8')

cv2.waitKey(0)
cv2.destroyAllWindows()

Это сообщение об ошибке: Обратите внимание, что у меня и img1, и маска в одной форме

Traceback (последний последний вызов):

Файл "", строка 1, в runfile ('C: /Users/User/Anaconda3/darkpixeldetection.py', wdir = 'C: / Users / User / Anaconda3')

Файл "C: \ Users \ User \ Anaconda3 \ Lib \ сайт-пакеты \ spyder_kernels \ подгоняет \ spydercustomize.py", строка 678, в runfile execfile (имя файла, пространство имен)

Файл "C: \ Users \ User \ Anaconda3 \ Lib \ сайт-пакеты \ spyder_kernels \ подгоняет \ spydercustomize.py", строка 106, в execfile exec (compile (f.read (), filename, 'exec'), пространство имен)

Файл "C: /Users/User/Anaconda3/darkpixeldetection.py", строка 69, в masked = (mask_stack * img1) + ((1-mask_stack) * mask_color)

ValueError: операнды не могут передаваться вместе с фигурами (1540,2670) (1540,2670,3)

Вывод img1.shape:

(1540,2670,3)

Выходные данные mask_stack.shape:

(1540,2670,3)

Фред: Это входное изображение , которое у меня размытое. Это выходное изображение , которое я получаю после удаления ненужных контуров Это мой код:

import numpy as np
import cv2
img_original= cv2.imread('blueimagewithblur.jpg')
img_array=np.asarray(img_original)
blur= cv2.pyrMeanShiftFiltering(img_original,21,49)

gray_image= cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)

ret,thresh= cv2.threshold(gray_image,70,255,cv2.THRESH_BINARY)

_, contours,hierarchy =cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

countourimage=cv2.drawContours(img_original,contours,-1,0,3)
largest_area= 2000

for i,c in enumerate(contours):
    contour_areas=cv2.contourArea(c)
    if(contour_areas>largest_area):
        del contours[i]
        x_rect,y_rect,w_rect,h_rect=cv2.boundingRect(c)
        cropped=img_original[y_rect:y_rect+h_rect,x_rect:x_rect+w_rect]

cv2.imwrite('C:/Users/User/Anaconda3/stackoverflowexam.jpg',cropped)
cv2.imshow('croopedd',cropped)


cv2.waitKey(0)
cv2.destroyAllWindows()

1 Ответ

0 голосов
/ 11 сентября 2018

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

maxArea  = 12412 # whatever makes sense in your case
for i, contour in enumerate(contours):
  area = cv2.contourArea(contour)
  if area > maxArea :
    del contours[i]
...