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




opencv image-processing (4)

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

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

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

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

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


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

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


निम्नलिखित कोड आपको आरंभ करना चाहिए। आप अपने निष्कर्षण को ठीक करने के लिए कार्यक्रम के शीर्ष पर मापदंडों के साथ खेलना चाहते हैं:

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)
# Previously, for a previous version of cv2, this line was: 
#  contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
# Thanks to notes from commenters, I've updated the code but left this note
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:


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

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

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

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

  • अब यह मानते हुए कि आपके पास विषय के चारों ओर एक निरंतर बढ़त है, धारित वस्तु के बाहर सभी बिंदुओं को मिलाने के लिए किसी भी प्रकार के फिल एल्गोरिथ्म (ब्लॉब) का उपयोग करें, फिर उस वस्तु का अंदर का मास्क देने के लिए उसे नकारात्मक लें। ।








scikit-image