cv::Mat::copyTo
कि क्या उत्पादन मैट्रिक्स प्रारंभ कर दिया गया है के आधार पर दो चीजों में से एक करता है जाना होगा। यदि आपका आउटपुट मैट्रिक्स प्रारंभ नहीं किया गया है, तो मास्क के साथ copyTo
का उपयोग करके एक नया आउटपुट मैट्रिक्स बनाता है जो इनपुट के समान प्रकार है और सभी मान सभी चैनलों पर 0 पर सेट होते हैं। एक बार ऐसा होने पर, मुखौटा द्वारा परिभाषित छवि डेटा को 0 पर सेट किए गए शेष मैट्रिक्स के साथ कॉपी किया जाता है। यदि आपका आउटपुट मैट्रिक्स प्रारंभ होता है और इसमें पहले से ही सामग्री शामिल है, copyTo
उन पिक्सेल पर प्रतियां जो परिभाषित हैं स्रोत से मुखौटा और पिक्सल छोड़ देता है जो गंतव्य में बरकरार रखने के लिए मुखौटा का हिस्सा नहीं थे। इसलिए, स्रोत छवि से मुखौटा द्वारा परिभाषित पिक्सल का प्रतिस्थापन आउटपुट पर कॉपी हो जाता है।
क्योंकि ओपनसीवी अब लाइब्रेरी के साथ इंटरफ़ेस के लिए numpy
का उपयोग करता है, तो यह या तो विधियों को करना बहुत आसान है। इस पोस्ट में देखे गए दूसरे उत्तर से अलग होने के लिए, पहली विधि को छवि के साथ मास्क को तत्व-वार फैशन में गुणा करके पूरा किया जा सकता है। यह मानते हुए कि अपने इनपुट img
कहा जाता है और अपने द्विआधारी मुखौटा mask
कहा जाता है जहां मैं यह सोचते हैं हूँ मुखौटा 2 डी है, बस निम्न कार्य करें:
import numpy as np
import cv2
mask = ... # define mask here
img = cv2.imread(...) # Define input image here
# Create new image
new_image = img * (mask.astype(img.dtype))
ऊपर कोड हालांकि मानता है कि दोनों img
और mask
शेयर के एक ही नंबर चैनल। यदि आप पहले से ही मान चुके हैं तो स्रोत और मास्क 2 डी के रूप में रंग छवि का उपयोग कर रहे हैं तो यह मुश्किल हो जाता है। इसलिए, चैनलों की कुल संख्या 2 है और 3 नहीं है और इसलिए उपर्युक्त वाक्यविन्यास आपको एक त्रुटि देगा क्योंकि दोनों के बीच आयाम अब संगत नहीं हैं। जब आप रंगीन छवियों का उपयोग कर रहे हों तो आपको इसके लिए समायोजित करने की आवश्यकता होगी। आप मुखौटा में सिंगलटन तीसरा आयाम जोड़ कर ऐसा कर सकते हैं ताकि प्रसारण का लाभ उठाया जा सके।
import numpy as np
import cv2
mask = ... # define mask here
img = cv2.imread(...) # Define input image here
# Create new image
# Case #1 - Other image is grayscale and source image is colour
if len(img.shape) == 3 and len(mask.shape) != 3:
new_image = img * (mask[:,:,None].astype(img.dtype))
# Case #2 - Both images are colour or grayscale
elif (len(img.shape) == 3 and len(mask.shape) == 3) or \
(len(img.shape) == 1 and len(mask.shape) == 1):
new_image = img * (mask.astype(img.dtype))
# Otherwise, we can't do this
else:
raise Exception("Incompatible input and mask dimensions")
दूसरा दृष्टिकोण के लिए, मान लेते हैं कि हम एक और छवि other_image
जहां आपको यह चित्र वापस लक्ष्य छवि img
करने के लिए अपने मुखौटा द्वारा परिभाषित में सामग्री कॉपी करना चाहते कहा जाता डालते हैं। इस मामले में, आप पहले क्या करेंगे मास्क में सभी स्थानों को निर्धारित करते हैं जो numpy.where
का उपयोग करके गैर-शून्य हैं, फिर इन्हें अपनी छवि में इंडेक्स या स्लाइस के साथ-साथ जहां से आप कॉपी करना चाहते हैं, का उपयोग करें। हम यह भी सिर्फ पहला दृष्टिकोण के साथ की तरह दो छवियों के बीच चैनलों की संख्या के प्रति जागरूक होना जरूरी:
import numpy as np
import cv2
mask = ... # define mask here
img = cv2.imread(...) # Define input image here
other_image = cv2.imread(...) # Define other image here
locs = np.where(mask != 0) # Get the non-zero mask locations
# Case #1 - Other image is grayscale and source image is colour
if len(img.shape) == 3 and len(other_image.shape) != 3:
img[locs[0], locs[1]] = other_image[locs[0], locs[1], None]
# Case #2 - Both images are colour or grayscale
elif (len(img.shape) == 3 and len(other_image.shape) == 3) or \
(len(img.shape) == 1 and len(other_image.shape) == 1):
img[locs[0], locs[1]] = other_image[locs[0], locs[1]]
# Otherwise, we can't do this
else:
raise Exception("Incompatible input and output dimensions")
यहाँ दोनों दृष्टिकोण के लिए एक उदाहरण रन है। मैं कैमरामैन छवि का उपयोग करने जा रहा हूं जो कि अधिकांश छवि प्रसंस्करण एल्गोरिदम में देखी गई एक मानक परीक्षण छवि है।
मैं भी कृत्रिम रूप से छवि रंग कर दिया है, भले ही यह ग्रेस्केल के रूप में देखा है, लेकिन तीव्रता सभी चैनलों को कॉपी कर दिए जाएंगे। मैं भी एक मुखौटा बस यह है कि शीर्ष छोड़ दिया 100 x 100 उपक्षेत्र परिभाषित करने के लिए जा रहा हूँ और इसलिए हम एक आउटपुट छवि बनाएगा कि केवल प्रतियां इस उपक्षेत्र:
import numpy as np
import cv2
# Define image
img = cv2.imread("cameraman.png")
# Define mask
mask = np.zeros(img.shape, dtype=np.bool)
mask[:100, :100] = True
आप पहली विधि का उपयोग करते हैं और जब हम परिणाम बताते हैं, हम पाते हैं:
हम देख सकते हैं कि हम एक आउटपुट छवि जहां शीर्ष छोड़ दिया 100 x 100 पिक्सल उपक्षेत्र 0. इस के बराबर सेट के बाकी के साथ हमारे छवि डेटा नहीं है बनाया मास्क स्थानों के अधीन है जो हैं True
पर सेट करें। दूसरे दृष्टिकोण के लिए, हम अन्य छवियों को एक ऐसे आकार के रूप में बनाएंगे जो सभी छवियों के लिए [0, 255]
से इनपुट छवि के समान आकार के यादृच्छिक है।
# Define other image
other_image = (255*np.random.rand(*img.shape)).astype(np.uint8)
एक बार जब हम दूसरे दृष्टिकोण के साथ कोड के माध्यम से चलाने, मैं अब इस छवि को मिलती है:
आप देख सकते हैं, चित्र के ऊपरी-बाएं कोने के रूप में अद्यतन किया गया है मास्क स्थानों के अधीन जो True
पर सेट हैं।
धन्यवाद, शानदार स्पष्टीकरण और निश्चित रूप से - यह काम करता है! – mikevanis
बहुत बहुत धन्यवाद! मैं खुशी से मदद कर सकता है। – rayryeng