python मैं इस तरह की छवि से पृष्ठभूमि को कैसे हटाऊं?




opencv image-processing (4)

मैं केवल व्यक्ति को प्राप्त करने के लिए इस छवि की पृष्ठभूमि को हटाना चाहता हूं। मेरे पास इस तरह की हजारों छवियां हैं, मूल रूप से, एक व्यक्ति और कुछ हद तक सफ़ेद पृष्ठभूमि।

मैंने जो किया है वह कैन एज डिटेक्टर या सोबेल फ़िल्टर ( skimage लाइब्रेरी से) जैसे एज डिटेक्टर का उपयोग करना है। फिर मुझे लगता है कि क्या करना संभव है, किनारों के भीतर पिक्सल को सफ़ेद करें और बिना पिक्सेल को ब्लैक करें। इसके बाद, मूल छवि केवल व्यक्ति की तस्वीर प्राप्त करने के लिए मुखौटा हो सकती है।

हालांकि, कैनी एज डिटेक्टर का उपयोग करके बंद सीमा प्राप्त करना मुश्किल है। सोबेल फ़िल्टर का उपयोग करना नतीजा बुरा नहीं है, हालांकि मैं वहां से आगे बढ़ना नहीं चाहता हूं।

संपादित करें:

क्या दाएं हाथ और स्कर्ट और बाल के बीच की पृष्ठभूमि को भी हटाना संभव है?


बनाम2017 के साथ कामकाजी उदाहरण।
लाल पृष्ठभूमि सेट करता है लेकिन नीला बचाता है ..
इसमें ट्रांसपेरेंट उदाहरण भी जोड़ा गया।

मैं लड़कियों के शरीर को कैसे हटा सकता हूं और तस्वीर में केवल पोशाक छोड़ सकता हूं? कोई विचार?

# == https://.com/questions/29313667/how-do-i-remove-the-background-from-this-kind-of-image

import cv2
import numpy as np
from matplotlib import pyplot as plt

#== Parameters =======================================================================
BLUR = 21
CANNY_THRESH_1 = 10
CANNY_THRESH_2 = 200
MASK_DILATE_ITER = 10
MASK_ERODE_ITER = 10
MASK_COLOR = (0.0,0.0,1.0) # In BGR format


#== Processing =======================================================================

#-- Read image -----------------------------------------------------------------------
img = cv2.imread('img/SYxmp.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#-- Edge detection -------------------------------------------------------------------
edges = cv2.Canny(gray, CANNY_THRESH_1, CANNY_THRESH_2)
edges = cv2.dilate(edges, None)
edges = cv2.erode(edges, None)

#-- Find contours in edges, sort by area ---------------------------------------------
contour_info = []
_, contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
for c in contours:
    contour_info.append((
        c,
        cv2.isContourConvex(c),
        cv2.contourArea(c),
    ))
contour_info = sorted(contour_info, key=lambda c: c[2], reverse=True)
max_contour = contour_info[0]

#-- Create empty mask, draw filled polygon on it corresponding to largest contour ----
# Mask is black, polygon is white
mask = np.zeros(edges.shape)
cv2.fillConvexPoly(mask, max_contour[0], (255))



#-- Smooth mask, then blur it --------------------------------------------------------
mask = cv2.dilate(mask, None, iterations=MASK_DILATE_ITER)
mask = cv2.erode(mask, None, iterations=MASK_ERODE_ITER)
mask = cv2.GaussianBlur(mask, (BLUR, BLUR), 0)

mask_stack = np.dstack([mask]*3)    # Create 3-channel alpha mask

#-- Blend masked img into MASK_COLOR background --------------------------------------
mask_stack  = mask_stack.astype('float32') / 255.0          # Use float matrices, 
img         = img.astype('float32') / 255.0                 #  for easy blending

masked = (mask_stack * img) + ((1-mask_stack) * MASK_COLOR) # Blend
masked = (masked * 255).astype('uint8')                     # Convert back to 8-bit 

plt.imsave('img/girl_blue.png', masked)
# split image into channels
c_red, c_green, c_blue = cv2.split(img)

# merge with mask got on one of a previous steps
img_a = cv2.merge((c_red, c_green, c_blue, mask.astype('float32') / 255.0))

# show on screen (optional in jupiter)
#%matplotlib inline
plt.imshow(img_a)
plt.show()

# save to disk
cv2.imwrite('img/girl_1.png', img_a*255)

# or the same using plt
plt.imsave('img/girl_2.png', img_a)

cv2.imshow('img', masked)                                   # Displays red, saves blue

cv2.waitKey()

निम्नलिखित कोड आपको शुरू करना चाहिए। आप अपने निष्कर्षण को सुदृढ़ करने के लिए प्रोग्राम के शीर्ष पर पैरामीटर के साथ खेलना चाह सकते हैं:

import cv2
import numpy as np

#== Parameters =======================================================================
BLUR = 21
CANNY_THRESH_1 = 10
CANNY_THRESH_2 = 200
MASK_DILATE_ITER = 10
MASK_ERODE_ITER = 10
MASK_COLOR = (0.0,0.0,1.0) # In BGR format


#== Processing =======================================================================

#-- Read image -----------------------------------------------------------------------
img = cv2.imread('C:/Temp/person.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#-- Edge detection -------------------------------------------------------------------
edges = cv2.Canny(gray, CANNY_THRESH_1, CANNY_THRESH_2)
edges = cv2.dilate(edges, None)
edges = cv2.erode(edges, None)

#-- Find contours in edges, sort by area ---------------------------------------------
contour_info = []
contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
for c in contours:
    contour_info.append((
        c,
        cv2.isContourConvex(c),
        cv2.contourArea(c),
    ))
contour_info = sorted(contour_info, key=lambda c: c[2], reverse=True)
max_contour = contour_info[0]

#-- Create empty mask, draw filled polygon on it corresponding to largest contour ----
# Mask is black, polygon is white
mask = np.zeros(edges.shape)
cv2.fillConvexPoly(mask, max_contour[0], (255))

#-- Smooth mask, then blur it --------------------------------------------------------
mask = cv2.dilate(mask, None, iterations=MASK_DILATE_ITER)
mask = cv2.erode(mask, None, iterations=MASK_ERODE_ITER)
mask = cv2.GaussianBlur(mask, (BLUR, BLUR), 0)
mask_stack = np.dstack([mask]*3)    # Create 3-channel alpha mask

#-- Blend masked img into MASK_COLOR background --------------------------------------
mask_stack  = mask_stack.astype('float32') / 255.0          # Use float matrices, 
img         = img.astype('float32') / 255.0                 #  for easy blending

masked = (mask_stack * img) + ((1-mask_stack) * MASK_COLOR) # Blend
masked = (masked * 255).astype('uint8')                     # Convert back to 8-bit 

cv2.imshow('img', masked)                                   # Display
cv2.waitKey()

#cv2.imwrite('C:/Temp/person-masked.jpg', masked)           # Save

ouput:


  • अपने अधूरे किनारों (जैसा कि आपके पास है) प्राप्त करने के बाद, आप एक बंद मोर्फोलॉजी (फैलाने और ईरोड का अनुक्रम) चला सकते हैं (किनारों की आवश्यकताओं / स्थिति के आधार पर आकार और पुनरावृत्तियों को सेट करना होगा)।

  • अब यह मानते हुए कि आपके पास विषय के चारों ओर एक निरंतर किनारा है, किनारे वाले ऑब्जेक्ट के बाहर सभी बिंदुओं को गठबंधन करने के लिए किसी भी प्रकार के भरने वाले एल्गोरिदम (ब्लोब) का उपयोग करें, फिर उस वस्तु के अंदर का मुखौटा देने के लिए इसका नकारात्मक लें ।


एक विकल्प के रूप में, आप इस तरह तंत्रिका नेटवर्क का उपयोग कर सकते हैं: CRFRNN

यह परिणाम इस तरह देता है:





scikit-image