OpenCV grabcut () background color and outline in Python

I am using Python and OpenCV. Now I am using grabcut()

to highlight the object I want. Here is my code:

img = cv2.imread('test.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
mask = np.zeros(img.shape[:2], np.uint8)

bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

rect = (2,2,630,930)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

mask2 = np.where((mask==2)|(mask==0), 0,1).astype('uint8')
img = img*mask2[:,:, np.newaxis]

      

enter image description here enter image description here

Then I try to find the outline.

I tried to find the outline by the code below:

imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

      

And it returns a contours array

long 48

. When I do this: enter image description here

First question: how can I get the outline (array) of this capture?

enter image description here Second question: as you can see, the background color is black. How do I change the background color to white?

Thank.

+2


source to share


2 answers


First you need to get the background. To this you need to subtract from the original image with the mask image. And then change the black background to white (or any color). And then add the mask image again.

import numpy as np
import cv2

cv2.namedWindow(‘image’, cv2.WINDOW_NORMAL)

#Load the Image
imgo = cv2.imread(‘input.jpg’)
height, width = imgo.shape[:2]

#Create a mask holder
mask = np.zeros(imgo.shape[:2],np.uint8)

#Grab Cut the object
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)

#Hard Coding the Rect… The object must lie within this rect.
rect = (10,10,width-30,height-30)
cv2.grabCut(imgo,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask = np.where((mask==2)|(mask==0),0,1).astype(‘uint8’)
img1 = imgo*mask[:,:,np.newaxis]

#Get the background
background = imgo – img1

#Change all pixels in the background that are not black to white
background[np.where((background > [0,0,0]).all(axis = 2))] =[255,255,255]

#Add the background and the image
final = background + img1

#To be done – Smoothening the edges….

cv2.imshow(‘image’, final )

k = cv2.waitKey(0)

if k==27:
cv2.destroyAllWindows()

      



Information obtained from the site https://nxtify.wordpress.com/2015/02/24/image-background-removal-using-opencv-in-python/

+6


source


If you want to have a single contour border, you can go to edge detection in the output of the grabcut extension and morphology in the edge image to get both the corresponding connected contour and get the border pixel array.



To make the background white, all pixels outside the frame can be made white by default. The black pixels inside your frame, you can compare to the original grayscale image, if it is black you can keep it, otherwise make it white. Because if the original pixel is not black, but made black by grabcut, then it is considered the background. If there is a black pixel in the foreground, grabcut never makes it black (ideal case).

-1


source







All Articles