2015-02-27 13 views
5

मैं रेटिनाल फंडस छवियों पर काम कर रहा हूं। छवि में काले रंग की पृष्ठभूमि पर गोलाकार रेटिना शामिल है। ओपनसीवी के साथ, मैंने एक परिसर प्राप्त करने में कामयाब रहा है जो पूरे परिपत्र रेटिना से घिरा हुआ है। मुझे काले पृष्ठभूमि से परिपत्र रेटिना को फसल करने की ज़रूरत है।एक समोच्च के आंतरिक क्षेत्र को कैसे फसल करें?

+2

क्या आप फसल मतलब है: इसलिए, बस पहले उत्पादन की अनदेखी करने के उपरोक्त कोड में cv2.findContours बयान बदलते हैं? छवियां हमेशा आयताकार होती हैं, इसलिए आप जो भी कर सकते हैं वह मास्क बनाते हैं और केवल मास्क किए गए पिक्सल पर आपके निम्नलिखित ऑपरेशन (प्रसंस्करण/प्रतिपादन) करते हैं। या आप छवि को फसल कर सकते हैं ताकि इसे रेटिना के बाउंडिंग बॉक्स द्वारा दर्शाया जा सके, जो मूल छवि से बहुत छोटा हो सकता है, लेकिन अभी भी कुछ काले हिस्से होंगे (क्योंकि रेटिना आयताकार नहीं है)।या आप रेटिना के अंदर अधिकतम आयताकार क्षेत्र में फसल कर सकते हैं, जिसमें कोई काला पृष्ठभूमि पिक्सल नहीं छोड़ेगा लेकिन रेटिना के हिस्सों को भी हटा देगा। आप कौन सा चाहते है? – Micka

+2

यदि यह अंतिम परिदृश्य है तो कृपया http://stackoverflow.com/questions/21410449/how-do-i-crop-to-largest-interior-bounding-box-in-opencv/21479072#21479072 – Micka

+0

@ गौरवपतिल - यद्यपि यह उत्तर कई साल पुराना है, मैं लगातार अपने उत्तर पर अपवित्र हो रहा हूं ... जिसका अर्थ है कि यह शायद सही है। अगर इससे आपको किसी भी तरह से मदद मिली है, तो मैं सराहना करता हूं कि अगर आप लोगों को यह बताने के लिए जवाब स्वीकार कर सकते हैं कि अब आपको इस संबंध में मदद की ज़रूरत नहीं है। धन्यवाद! – rayryeng

उत्तर

17

यह आपके प्रश्न में अस्पष्ट है कि क्या आप वास्तव में समोच्च के भीतर परिभाषित की गई जानकारी को फसल करना चाहते हैं या उस जानकारी को मुखौटा करना चाहते हैं जो चुने गए समोच्च से प्रासंगिक नहीं है। मैं पता लगाऊंगा कि दोनों परिस्थितियों में क्या करना है।


जानकारी

मान लिया जाये कि आप अपनी छवि पर cv2.findContours दौड़ा बाहर मास्किंग, आप एक संरचना है कि आकृति अपनी छवि में उपलब्ध सभी सूचीबद्ध करता है प्राप्त हुआ होगा। मैं यह भी मान रहा हूं कि आप इंडेक्स समोच्च के बारे में जानते हैं जो आपके इच्छित ऑब्जेक्ट को घेरने के लिए उपयोग किया गया था। मान लीजिए कि यह idx में संग्रहीत है, पहले को रिक्त छवि पर इस समोच्च के संस्करण को भरने के लिए cv2.drawContours का उपयोग करें, फिर ऑब्जेक्ट निकालने के लिए इस छवि का उपयोग अपनी छवि में इंडेक्स करने के लिए करें। यह तर्क मास्क किसी भी अप्रासंगिक जानकारी से बाहर है और केवल महत्वपूर्ण है जो आपके द्वारा चुने गए समोच्च के भीतर परिभाषित किया गया है।

import numpy as np 
import cv2 
img = cv2.imread('...', 0) # Read in your image 
contours, _ = cv2.findContours(...) # Your call to find the contours 
idx = ... # The index of the contour that surrounds your object 
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise 
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask 
out = np.zeros_like(img) # Extract out the object and place into output image 
out[mask == 255] = img[mask == 255] 

# Show the output image 
cv2.imshow('Output', out) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

आप वास्तव में कांट-छांट करना चाहते हैं ...

आप फसल करना चाहते हैं: कोड संभालने अपनी छवि ग्रेस्केल छवि img में संग्रहित है यह निम्नलिखित कुछ ऐसा दिखाई देगा करने के लिए, छवि, आपको समोच्च द्वारा परिभाषित क्षेत्र के न्यूनतम स्पैनिंग बाउंडिंग बॉक्स को परिभाषित करने की आवश्यकता है। आप बाउंडिंग बॉक्स के ऊपरी बाएं और निचले दाएं कोने को पा सकते हैं, फिर आपको जो चाहिए उसे फसल करने के लिए अनुक्रमण का उपयोग करें। कोड पहले की तरह ही होगा, लेकिन एक अतिरिक्त फसल कदम होगा:

import numpy as np 
import cv2 
img = cv2.imread('...', 0) # Read in your image 
contours, _ = cv2.findContours(...) # Your call to find the contours 
idx = ... # The index of the contour that surrounds your object 
mask = np.zeros_like(img) # Create mask where white is what we want, black otherwise 
cv2.drawContours(mask, contours, idx, 255, -1) # Draw filled contour in mask 
out = np.zeros_like(img) # Extract out the object and place into output image 
out[mask == 255] = img[mask == 255] 

# Now crop 
(x, y) = np.where(mask == 255) 
(topx, topy) = (np.min(x), np.min(y)) 
(bottomx, bottomy) = (np.max(x), np.max(y)) 
out = out[topx:bottomx+1, topy:bottomy+1] 

# Show the output image 
cv2.imshow('Output', out) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

फसल कोड इस तरह है कि जब हम मुखौटा क्षेत्र समोच्च द्वारा परिभाषित बाहर निकालने के लिए परिभाषित करते हैं, हम इसके साथ ही लगता है काम करता है सबसे छोटे क्षैतिज और ऊर्ध्वाधर निर्देशांक जो समोच्च के ऊपरी बाएं कोने को परिभाषित करते हैं। हम इसी तरह सबसे बड़े क्षैतिज और लंबवत निर्देशांक पाते हैं जो समोच्च के निचले बाएं कोने को परिभाषित करते हैं। इसके बाद हम इन निर्देशांकों के साथ इंडेक्सिंग का उपयोग करते हैं जो हमें वास्तव में चाहिए। ध्यान दें कि यह मास्क किए गए छवि पर फसल का प्रदर्शन करता है - यह वह छवि है जो सबकुछ हटाती है लेकिन सबसे बड़ी समोच्च में मौजूद जानकारी को हटा देती है। OpenCV 3.x के साथ

नोट

ऐसा लगता है ऊपर कोड मानता है कि आप OpenCV 2.4.x. उपयोग कर रहे हैं ध्यान दें कि ओपनसीवी 3.x में, cv2.drawContours की परिभाषा बदल गई है। विशेष रूप से, आउटपुट एक तीन तत्व ट्यूपल आउटपुट होता है जहां पहली छवि स्रोत छवि होती है, जबकि अन्य दो पैरामीटर OpenCV 2.4.x के समान होते हैं।

_, contours, _ = cv2.findContours(...) # Your call to find contours 
+0

@ रीडेट गेटाजू - नहीं, निर्देशांक स्वैप नहीं किए गए हैं। 'Np.where' का आउटपुट' x' में पंक्ति स्थानों और 'y' में कॉलम स्थानों को प्रदान करता है जो शून्य नहीं हैं। इसलिए, सरणी में अनुक्रमण करना सही है। कृपया संपादन का सुझाव देने से पहले वास्तव में अपने परिवर्तनों का परीक्षण करें। – rayryeng

संबंधित मुद्दे