0

I would like to remove the black part in the background or change it to a different colour as I am trying to detect dark pixel inside the contour and this does not seem to work since both are in black background and the dark pixels are black...

This is what i have tried but please suggest any other method possible..Thanks in advance

I have tried to extract the background which is black and change it to yellow

Please find my code below:

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)

I have then taken help of this: How do I remove the background from this kind of image?

This was to blend the original image with the background created but does not seem to work and gives out an error

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()

This is the error message: Note that I have both the img1 and the mask in the same shape

Traceback (most recent call last):

File "", line 1, in runfile('C:/Users/User/Anaconda3/darkpixeldetection.py', wdir='C:/Users/User/Anaconda3')

File "C:\Users\User\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 678, in runfile execfile(filename, namespace)

File "C:\Users\User\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 106, in execfile exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/User/Anaconda3/darkpixeldetection.py", line 69, in masked= (mask_stack *img1)+((1-mask_stack)*mask_color)

ValueError: operands could not be broadcast together with shapes (1540,2670) (1540,2670,3)

Output of img1.shape:

(1540,2670,3)

Output of mask_stack.shape :

(1540,2670,3)

Fred: This is the input image that I have which has blurred content. This is the output image that I get after deleting the unnecessary contours This is my code:

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()
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87

1 Answers1

0

You can use the fact that the background occupies a large part of your image. If you know that what you want to detect is always smaller than a certain size, you can use the contour area to filter which contours to ignore.

maxArea  = 12412 # whatever makes sense in your case
for i, contour in enumerate(contours):
  area = cv2.contourArea(contour)
  if area > maxArea :
    del contours[i]
Fred Guth
  • 1,537
  • 1
  • 15
  • 27
  • Thanks for the response, when i tried to find the largest contour in the image, it actually finds that square as the largest, i do these following steps and then save it to the image, that is where the actual problem is, when i get this cropped image as it is not perfectly parallel to the ground and is inclined so i also get the black background while cropping..find the steps in the next comment –  Sep 11 '18 at 07:18
  • largest_area=0 for i, c in enumerate(contours): contour_area=cv2.contourArea(c) if (contour_area > largest_area): largest_area=contour_area x, y, w, h = cv2.boundingRect(c) cropped= image[y :y + h, x : x + w ] cv2.imshow('cropped_region', cropped) cv2.imwrite('Path',cropped) cv2.waitKey(0) –  Sep 11 '18 at 07:22
  • You don't want to find the biggest contour. you want to find contours that are smaller than a certain area. Let's say your circles are roughly smaller than 200 x 200 pixels. Than your maxArea will be 40000. – Fred Guth Sep 11 '18 at 12:02
  • actually i have like 150images and everyimage has inclined screen and some of them also has blurred content on the screen, I have added images for the reference in the earlier, check :) . So i set my maxarea=2000(because my defective pixels could be of that size) and as u said its absolutely right that i want the screen and these pixels inside and we can remove the contours > than this max area to get rid of the black part of the image. In case of blurred images, it gives me the output completely incorrect,it elimates the whole lcd screen and gives me the output with the blurred content –  Sep 12 '18 at 10:04
  • 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] –  Sep 12 '18 at 10:08
  • I have added a screen shot of my code in the edited post pleaseee check :) Thanks in advance –  Sep 12 '18 at 10:09
  • I am confused by the last image you shared. You have a blurred rectangle inside a dark background. What do you want your code to detect? – Fred Guth Sep 12 '18 at 16:48
  • I want it to detect only the center part of it thats the screen and then crop it so that i can find defects inside that –  Sep 14 '18 at 06:53