python एक छवि से सबसे बड़ा आयताकार कैसे फसल करें




opencv image-processing (2)

मेरे पास एक टेबल पर पृष्ठों की कुछ छवियां हैं I मैं छवियों से छवियों को फसल करना चाहता हूं। आम तौर पर, पृष्ठ छवि में सबसे बड़ा आयताकार होगा, हालांकि आयत के सभी चार पक्ष कुछ मामलों में दिखाई नहीं दे सकते हैं।

मैं निम्नलिखित कर रहा हूं लेकिन वांछित परिणाम नहीं प्राप्त कर रहा हूं:

import cv2
import numpy as np

im = cv2.imread('images/img5.jpg')
gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,0)
_,contours,_ = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt=contours[max_index]
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("Show",im)
cv2.imwrite("images/img5_rect.jpg", im)
cv2.waitKey(0)

नीचे कुछ उदाहरण दिए गए हैं:

पहला उदाहरण : मैं इस छवि में आयताकार पा सकता हूं, हालांकि, अगर लकड़ी के शेष हिस्से को भी बाहर निकाला जा सकता है।

दूसरा उदाहरण : इस छवि में आयत के सही आयामों को नहीं ढूंढ रहा है।

तीसरा उदाहरण : इस छवि में सही आयामों को खोजने में सक्षम नहीं है।

चौथा उदाहरण : इसके साथ ही।


जैसा कि मैंने पहले कुछ ऐसा किया है, मैंने आटा परिवर्तन के साथ अनुभव किया है, लेकिन वे अपने मामले के लिए समोच्चों का उपयोग करने के लिए सही होने के लिए बहुत कठिन थे। शुरू करने में आपकी सहायता के लिए मेरे पास निम्नलिखित सुझाव हैं:

  1. आम तौर पर पेपर (किनारों, कम से कम) सफेद होता है, इसलिए आपको यूयूवी जैसे रंगस्थान पर जाकर बेहतर भाग्य हो सकता है जो चमकदारता को बेहतर ढंग से अलग करता है:

    image_yuv = cv2.cvtColor(image,cv2.COLOR_BGR2YUV)
    image_y = np.zeros(image_yuv.shape[0:2],np.uint8)
    image_y[:,:] = image_yuv[:,:,0]
    
  2. कागज पर पाठ एक समस्या है। इन उच्च आवृत्ति शोर को हटाने (उम्मीद है) को धुंधला प्रभाव का उपयोग करें। आप मस्तिष्क संबंधी परिचालनों का भी उपयोग कर सकते हैं जैसे कि फैलाव भी।

    image_blurred = cv2.GaussianBlur(image_y,(3,3),0)
    
  3. आप एक साधारण थ्रेसहोल्ड की बजाय एक कैनी एज-डिटेक्टर को लागू करने का प्रयास कर सकते हैं। जरूरी नहीं है, लेकिन आपकी मदद कर सकता है:

     edges = cv2.Canny(image_blurred,100,300,apertureSize = 3)
    
  4. फिर समोच्च खोजें। मेरे मामले में मैंने केवल चरम बाहरी रूपों का उपयोग किया था। आप समोच्च को संपीड़ित करने के लिए CHAIN_APPROX_SIMPLE ध्वज का उपयोग कर सकते हैं

    contours,hierarchy = cv2.findContours(edges,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    
  5. अब आपके पास समोच्चों का गुच्छा होना चाहिए। सही खोजने के लिए समय। प्रत्येक समोच्च cnt , पहले उत्तल approaxPolyDP , फिर जितना संभव हो सके समोच्च को सरल बनाने के लिए approaxPolyDP का उपयोग करें।

    hull = cv2.convexHull(cnt)
    simplified_cnt = cv2.approxPolyDP(hull,0.001*cv2.arcLength(hull,True),True)
    
  6. अब हमें संलग्न चतुर्भुज को खोजने के लिए इस सरलीकृत समोच्च का उपयोग करना चाहिए। आप जिन नियमों के साथ आते हैं उनके साथ आप प्रयोग कर सकते हैं। सबसे आसान तरीका समोच्च के चार सबसे लंबे खंडों को चुन रहा है, और फिर इन चार लाइनों को छेड़छाड़ करके संलग्न चतुर्भुज बनाते हैं। आपके मामले के आधार पर, आप इन लाइनों को रेखा के विपरीत, कोण और समान चीजों के आधार पर पा सकते हैं।

  7. अब आपके पास चतुर्भुज का गुच्छा है। अब आप अपने आवश्यक चतुर्भुज को खोजने के लिए दो चरण विधि कर सकते हैं। सबसे पहले आप उन लोगों को हटा दें जो शायद गलत हैं। उदाहरण के लिए चतुर्भुज का एक कोण 175 डिग्री से अधिक है। फिर आप अंतिम परिणाम के रूप में सबसे बड़े क्षेत्र के साथ एक चुन सकते हैं। आप नारंगी समोच्च को इस बिंदु पर प्राप्त परिणामों में से एक के रूप में देख सकते हैं:

  8. सही चतुर्भुज (उम्मीद है) खोजने के बाद अंतिम चरण, एक आयताकार में बदल रहा है। इसके लिए आप एक रूपांतरण मैट्रिक्स के साथ आने के लिए findHomography का उपयोग कर सकते हैं।

    (H,mask) = cv2.findHomography(cnt.astype('single'),np.array([[[0., 0.]],[[2150., 0.]],[[2150., 2800.]],[[0.,2800.]]],dtype=np.single))
    

    संख्या पत्र पत्र के लिए प्रक्षेपण मानते हैं। आप उपयोग करने के लिए बेहतर और अधिक चालाक संख्या के साथ आ सकते हैं। आपको पत्र पत्र के निर्देशांक के आदेश से मेल खाने के लिए समोच्च बिंदुओं को फिर से व्यवस्थित करने की भी आवश्यकता है। फिर आप अंतिम छवि बनाने के लिए warpPerspective को कॉल करते हैं:

    final_image = cv2.warpPerspective(image,H,(2150, 2800))
    

    इस warping के परिणामस्वरूप निम्नलिखित की तरह कुछ होना चाहिए (मेरे परिणामों से पहले):

मुझे आशा है कि यह आपको अपने मामले में उचित दृष्टिकोण खोजने में मदद करेगा।


यह एक बहुत ही जटिल कार्य है जिसे आसानी से समोच्च खोजकर हल नहीं किया जा सकता है। उदाहरण के लिए अर्थशास्त्री कवर केवल पत्रिका के 1 किनारे को दिखाता है जो छवि को आधे हिस्से में विभाजित करता है। आपके कंप्यूटर को कैसे पता होना चाहिए कि कौन सा पत्रिका है और कौन सा टेबल है? तो आपको अपने कार्यक्रम में और अधिक बुद्धिमानी जोड़नी होगी।

आप अपनी छवि में लाइनों की तलाश कर सकते हैं। उदाहरण के लिए हफ़ ट्रांसफॉर्म। फिर अधिक या कम समांतर या ऑर्थोगोनल लाइनों के सेट खोजें, एक निश्चित लंबाई की रेखाएं ... सामान्य प्रिंट रंगों या रंगों की जांच करके प्रिंट ढूंढें जिन्हें आप आमतौर पर किसी तालिका पर नहीं पाते हैं। मुद्रित ग्रंथों द्वारा बनाए गए उच्च विपरीत आवृत्तियों की खोज करें ... कल्पना करें कि आप कैसे एक मानव के रूप में मुद्रित कागज को पहचानते हैं ...

यह सब स्टैक ओवरफ्लो के लिए एक बहुत व्यापक सवाल है। इसे छोटी उप-समस्याओं में विभाजित करने का प्रयास करें, उन्हें हल करने का प्रयास करें और यदि आप दीवार दबाते हैं, तो यहां वापस आएं।







image-processing