2009-09-24 8 views
6

मुझे सैद्धांतिक समझ है कि बाइनरी छवि में कितना फैलाव हुआ है।क्षरण को कार्यान्वित करना, सी में सीडी, सी ++

AFAIK, अगर मेरे एसई (संरचना तत्व) इस

0 1 
1 1. 

जहां है। केंद्र का प्रतिनिधित्व करता है, और मेरी छवि

0 0 0 0 0 
0 1 1 0 0 
0 1 0 0 0 
0 1 0 0 0 
0 0 0 0 0 

इतना फैलाव का परिणाम

0 1 1 0 0 
1 1 1 0 0 
1 1 0 0 0 
1 1 0 0 0 
0 0 0 0 0 

मैं 0 में छवि बदलने वाले, +1 (ऊपर) और और से परिणाम से ऊपर हो गया है (बाइनरी यह है) - एसई के अनुसार 1 (बाएं) दिशा, और इन सभी तीन बदलावों का संघ लेना।

अब, मुझे यह पता लगाने की आवश्यकता है कि सी, सी ++ में इसे कैसे कार्यान्वित किया जाए। मुझे यकीन नहीं है कि कैसे शुरू करें और सेट के संघ को कैसे लेना है। मैंने मूल छवि, तीन स्थानांतरित छवियों और यूनियन लेने से प्राप्त अंतिम छवि का प्रतिनिधित्व करने के बारे में सोचा; सभी मैट्रिक्स का उपयोग कर।

क्या कोई ऐसी जगह है जहां मुझे कुछ नमूना समाधान शुरू हो सकता है या आगे बढ़ने के लिए कोई विचार हो सकता है?

धन्यवाद।

उत्तर

10

वहाँ नमूना कार्यान्वयन की टन कर रहे हैं .. Google अपने दोस्त :)

संपादित है
निम्नलिखित (प्रक्रिया का एक छद्म कोड बहुत है 2 डी में एक रूपांतरण करने के समान)। इम यकीन है कि वहाँ यह करने के लिए अधिक चतुर तरीका है:

// grayscale image, binary mask 
void morph(inImage, outImage, kernel, type) { 
// half size of the kernel, kernel size is n*n (easier if n is odd) 
sz = (kernel.n - 1)/2; 

for X in inImage.rows { 
    for Y in inImage.cols { 

    if (isOnBoundary(X,Y, inImage, sz)) { 
    // check if pixel (X,Y) for boundary cases and deal with it (copy pixel as is) 
    // must consider half size of the kernel 
    val = inImage(X,Y);  // quick fix 
    } 

    else { 
    list = []; 

    // get the neighborhood of this pixel (X,Y) 
    for I in kernel.n { 
    for J in kernel.n { 
     if (kernel(I,J) == 1) { 
     list.add(inImage(X+I-sz, Y+J-sz)); 
     } 
    } 
    } 

    if type == dilation { 
    // dilation: set to one if any 1 is present, zero otherwise 
    val = max(list); 
    } else if type == erosion { 
    // erosion: set to zero if any 0 is present, one otherwise 
    val = min(list); 
    } 
    } 

    // set output image pixel 
    outImage(X,Y) = val; 
    } 
} 
} 

ऊपर कोड इस tutorial पर आधारित है (पृष्ठ के अंत में स्रोत कोड की जांच)।


EDIT2:

list.add (inImage (एक्स + मैं-SZ, वाई + J-SZ));

विचार है कि हम (आकार nxn का) कर्नेल मुखौटा वर्तमान छवि (एक्स, वाई) में स्थित पिक्सेल पर SZ (नकाब के आधे आकार) पर केन्द्रित मिलाती हैं करना चाहते हैं, और फिर बस तीव्रता मिल पिक्सल का जहां मास्क मान एक है (हम उन्हें एक सूची में जोड़ रहे हैं)। एक बार उस पिक्सेल के लिए सभी पड़ोसियों को निकालने के बाद, हमने आउटपुट छवि पिक्सेल को अधिकतम सूची (अधिकतम तीव्रता) में फैलाव के लिए सेट किया, और क्षरण के लिए न्यूनतम (निश्चित रूप से यह केवल ग्रेस्केल छवियों और बाइनरी मास्क के लिए काम करता है)
के सूचकांक ऊपर दिए गए बयान में एक्स/वाई और आई/जे दोनों कोसे शुरू करने के लिए माना जाता है यदि आप चाहें, तो आप हमेशा मास्क के आधे आकार के मामले में I/J के सूचकांक को फिर से लिख सकते हैं (से -z से + sz तक) एक छोटे से बदलाव के साथ (जिस तरह से मैंने ट्यूटोरियल का उपयोग किया है) ...


उदाहरण:
इस 3x3 गिरी मुखौटा रखा जाता है और पिक्सेल (एक्स, वाई) पर केन्द्रित विचार करें, और देखते हैं कि कैसे हम इसे चारों ओर पड़ोस पार:

-------------------- 
|  |  |  | sz = 1; 
--------------------  for (I=0 ; I<3 ; ++I) 
|  | (X,Y) |  |  for (J=0 ; J<3 ; ++J) 
--------------------   vect.push_back(inImage.getPixel(X+I-sz, Y+J-sz)); 
|  |  |  | 
-------------------- 
+0

और हमारे मामले में जहां कर्नेल आकार MxN = 1x3 है जहां एम चौड़ाई है और एन ऊंचाई है? – svlada

+0

कोड केवल एक रूपरेखा होने का मतलब था वास्तविक कार्यान्वयन नहीं। लेकिन यदि आप बारीकी से देखते हैं, तो आप देखेंगे कि मैंने केवल एन * एन कर्नेल के साथ निपटाया है जिसमें एन अजीब संख्या है .. – Amro

+0

:) हाँ, मैं इसे देखता हूं। सिर्फ यह कहना चाहता था कि आप कर्नेलविड्थ कर्नेल जोड़कर बस अपने कोड को बेहतर बना सकते हैं और सीमाओं की जांच कर सकते हैं। – svlada

2

शायद एक बेहतर तरीका देखने के लिए इस पर फैलाव के आउटपुट पिक्सेल का उत्पादन कैसे किया जाता है। छवि में इसी पिक्सेल के लिए, संरचना तत्व को संरेखित करें जैसे कि संरचना तत्व का मूल उस छवि पिक्सेल पर है। यदि कोई ओवरलैप है, तो उस स्थान पर फैलाव आउटपुट पिक्सेल को 1 पर सेट करें, अन्यथा इसे 0 पर सेट करें।

तो यह छवि में प्रत्येक पिक्सेल पर बस लूप करके किया जा सकता है और परीक्षण किया जा सकता है कि सही ढंग से स्थानांतरित संरचना तत्व छवि के साथ ओवरलैप करता है। इसका मतलब है कि आपके पास शायद 4 नेस्टेड लूप होंगे: x img, y img, x se, y se। तो प्रत्येक छवि पिक्सेल के लिए, आप संरचना तत्व के पिक्सल पर लूप करते हैं और देखते हैं कि कोई ओवरलैप है या नहीं। यह सबसे कुशल एल्गोरिदम नहीं हो सकता है, लेकिन यह शायद सबसे सरल है।

इसके अलावा, मुझे लगता है कि आपका उदाहरण गलत है। फैलाव संरचना तत्व की उत्पत्ति पर निर्भर करता है। मूल है ...

शीर्ष पर

शून्य छोड़ दिया: आप छवि (-1, -1), (-1,0) शिफ्ट करने के लिए की जरूरत है, और (0, -1) दे रही है:

1 1 1 0 0 
1 1 0 0 0 
1 1 0 0 0 
1 0 0 0 0 
0 0 0 0 0 
नीचे दाईं ओर स्थित

: आप छवि (0,0) शिफ्ट करने के लिए की जरूरत है, (1,0), और (0,1) दे रही है:

0 0 0 0 0 
0 1 1 1 0 
0 1 1 0 0 
0 1 1 0 0 
0 1 0 0 0 

MATLAB मंजिल ((आकार का उपयोग करता (एसई) +1)/2) एसई की उत्पत्ति के रूप में इस मामले में, यह एसई के शीर्ष बाएं पिक्सेल का उपयोग करेगा। आप इसे का उपयोग करके MATLAB फ़ंक्शन का उपयोग करके सत्यापित कर सकते हैं।

0
/* structure of the image variable 
* variable n stores the order of the square matrix */ 

typedef struct image{ 
     int mat[][]; 
     int n; 
     }image; 


/* function recieves image "to dilate" and returns "dilated"* 
* structuring element predefined: 
*    0 1 0 
*    1 1 1 
*    0 1 0 
*/ 

image* dilate(image* to_dilate) 
{ 
     int i,j; 
     int does_order_increase; 
     image* dilated; 

     dilated = (image*)malloc(sizeof(image)); 
     does_order_increase = 0; 

/* checking whether there are any 1's on d border*/  

     for(i = 0 ; i<to_dilate->n ; i++) 
     { 
      if((to_dilate->a[0][i] == 1)||(to_dilate->a[i][0] == 1)||(to_dilate->a[n-1][i] == 1)||(to_dilate->a[i][n-1] == 1)) 
      { 
       does_order_increase = 1; 
       break; 
      } 
     } 

/* size of dilated image initialized */  

     if(does_order_increase == 1) 
      dilated->n = to_dilate->n + 1; 
     else 
      dilated->n = to_dilate->n; 

/* dilating image by checking every element of to_dilate and filling dilated * 
* does_order_increase serves to cope with adjustments if dilated 's order increase */ 

     for(i = 0 ; i<to_dilate->n ; i++) 
     { 
      for(j = 0 ; j<to_dilate->n ; j++) 
      { 
       if(to_dilate->a[i][j] == 1) 
       { 
        dilated->a[i + does_order_increase][j + does_order_increase] = 1; 
        dilated->a[i + does_order_increase -1][j + does_order_increase ] = 1; 
        dilated->a[i + does_order_increase ][j + does_order_increase -1] = 1; 
        dilated->a[i + does_order_increase +1][j + does_order_increase ] = 1; 
        dilated->a[i + does_order_increase ][j + does_order_increase +1] = 1; 
       } 
      } 
     } 

/* dilated stores dilated binary image */ 

     return dilated; 
} 

/* end of dilation */ 
संबंधित मुद्दे