<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kantenerkennug]]></title><description><![CDATA[<p>Hallo,<br />
ich möchte die Kante eines fast elliptischen Objekts erkennen und einen Laser so ansteuern das er die Kontur der Kante nachfährt (mit Visual C++). Mit dem Sobel-Operator (und der entsprechenden Beleuchtung) funktioniert die Erkennung ganz gut.<br />
Allerdings möchte ich „nur“ die Kante des Objekts erkennen und nicht noch diverse Punkte in meinem Objekt, damit ich, die als Bitmap gespeicherte Kante, direkt zur Ansteuerung des Lasers benutzen kann.<br />
Wie erkennt man nur die Außenkante des Objekts bzw. eliminiert Einzelpunkte die nicht zum Rand des Objekts gehören (evtl. irgendein Faltungsoperator... )?<br />
Bitte leicht verständlich Antworten, bin absoluter Programmierneuling.<br />
Vielen Dank<br />
Dom</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/180406/kantenerkennug</link><generator>RSS for Node</generator><lastBuildDate>Mon, 21 Sep 2026 20:33:40 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/180406.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 02 May 2007 10:53:02 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Kantenerkennug on Wed, 02 May 2007 10:53:02 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich möchte die Kante eines fast elliptischen Objekts erkennen und einen Laser so ansteuern das er die Kontur der Kante nachfährt (mit Visual C++). Mit dem Sobel-Operator (und der entsprechenden Beleuchtung) funktioniert die Erkennung ganz gut.<br />
Allerdings möchte ich „nur“ die Kante des Objekts erkennen und nicht noch diverse Punkte in meinem Objekt, damit ich, die als Bitmap gespeicherte Kante, direkt zur Ansteuerung des Lasers benutzen kann.<br />
Wie erkennt man nur die Außenkante des Objekts bzw. eliminiert Einzelpunkte die nicht zum Rand des Objekts gehören (evtl. irgendein Faltungsoperator... )?<br />
Bitte leicht verständlich Antworten, bin absoluter Programmierneuling.<br />
Vielen Dank<br />
Dom</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1277444</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277444</guid><dc:creator><![CDATA[Gorilla]]></dc:creator><pubDate>Wed, 02 May 2007 10:53:02 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Wed, 02 May 2007 11:43:07 GMT]]></title><description><![CDATA[<p>Ein genaueres Vorgehn ist sehr stark von der Bildqualität abhängig (Signal/Rauschen, Ausleuchtung, etc.). Dein Problem liegt also eher in der Bildverarbeitung, d.h. du bist hier im C/C++ Teil eigentlich falsch.</p>
<p>Um kleinere Objekt zu eliminieren kannst du eventuell mit Median-Filter etc. vorverarbeiten, oder nach der Sobel-Segmentierung mit morphologischen Operatoren filtern.</p>
<p>Viele Grüße,</p>
<p>Tobias</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1277481</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277481</guid><dc:creator><![CDATA[TheBigW]]></dc:creator><pubDate>Wed, 02 May 2007 11:43:07 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Wed, 02 May 2007 12:02:09 GMT]]></title><description><![CDATA[<p>Rot-, Grün-, Blauwerte abfragen und vergleichen ?<br />
So etwas in der Art ?</p>
<pre><code class="language-cpp">#define Kontur_Max 0xFFFFFF
#define Kontur_Min 0xFFFF00

if ( rgbPixel &lt; 0xFFFFFF &amp;&amp; rgbPixel &gt; 0xFFFF00 )
{
 ...   // Ziehe diesen Pixel für die Kontur-Bestimmung in Betracht.
}
</code></pre>
<p>MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1277489</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277489</guid><dc:creator><![CDATA[rgb bmp]]></dc:creator><pubDate>Wed, 02 May 2007 12:02:09 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Wed, 02 May 2007 17:27:12 GMT]]></title><description><![CDATA[<p>Danke für Eure Antworten! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /><br />
TheBigW meinst Du mit Sobel-Segmentierung so etwas bzw. was haltet Ihr davon:</p>
<p>1. Zunächst mal Gauss-Filter um gröbstes Rauschen zu eliminieren.<br />
2. Segmentierung mit Grauwert-Diagramm. Bitmap daraus machen.<br />
3. Sobel-Operator anwenden</p>
<p>So müsste das doch funktionieren, oder?<br />
Hat mir jemand ein C++ Beispiel für die Segmentierung mit Grauwert-Diagramm?<br />
Danke<br />
Dom</p>
<p>In welches Forum sollte ich meinen Beitrag denn schreiben TheBigW? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1277765</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277765</guid><dc:creator><![CDATA[Gorilla]]></dc:creator><pubDate>Wed, 02 May 2007 17:27:12 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Wed, 02 May 2007 17:49:43 GMT]]></title><description><![CDATA[<p>Ist schon einige Zeit her, dass ich das hier verzapft hab- und unsauber ohne Ende, aber die wesentlichen Sachen kannst du dir da bestimmt rausziehen..</p>
<pre><code class="language-cpp">#include &lt;windows.h&gt;
#include &quot;cmyimg.h&quot;

#define p2(x,y)  ((y - 1) * this-&gt;bmih.biWidth + x    ) * 3
#define p3(x,y)  ((y - 1) * this-&gt;bmih.biWidth + x + 1) * 3
#define p4(x,y)  ((y    ) * this-&gt;bmih.biWidth + x + 1) * 3
#define p5(x,y)  ((y + 1) * this-&gt;bmih.biWidth + x + 1) * 3
#define p6(x,y)  ((y + 1) * this-&gt;bmih.biWidth + x    ) * 3
#define p7(x,y)  ((y + 1) * this-&gt;bmih.biWidth + x - 1) * 3
#define p8(x,y)  ((y    ) * this-&gt;bmih.biWidth + x - 1) * 3
#define p9(x,y)  ((y - 1) * this-&gt;bmih.biWidth + x - 1) * 3

/**
 * Konstruktor 
 * @param w Breite des Bildes in Pixeln
 * @param h Höhe des Bildes in Pixeln
 * @param f Datenformat
 * Mögliche Werte:
 *      IMG_RGB - RotGrünBlau-Bild
 *      IMG_GBR - GrünBlauRot-Bild
 */
cMyImage::cMyImage (BITMAPINFOHEADER bm, int f, unsigned char *lpd) {

    CopyMemory(&amp;this-&gt;bmih, &amp;bm, sizeof(BITMAPINFOHEADER)); 
    format  = f;

    /* Speicher auf bild legen */
    this-&gt;imgsize = this-&gt;bmih.biSizeImage;
//    this-&gt;lpdata = new unsigned char [imgsize];

    DIBSec  = CreateDIBSection( NULL, (BITMAPINFO *) &amp;bmih, 
                                        DIB_RGB_COLORS, (void**)&amp;lpdata, 
                                        NULL, 0
                                      );
    CopyMemory ((LPVOID) lpdata, (LPVOID) lpd, imgsize);

    switch (format) { 
        /* Indize für das jeweilige Datenformat beschreiben */
        case IMG_RGB:
                indexR = 0;
                indexB = 1;
                indexG = 2;
                break;
        case IMG_GBR:
                indexR = 2;
                indexB = 1;
                indexG = 0;
                break;
    }
}
/**
 * Destructor
 */
cMyImage::~cMyImage () { 
    /* Speicher freigeben */
    DeleteObject(DIBSec);
    delete lpdata;
}

/**
 * Konvertieren des Bildes nach Grauwertbild
 * @return cMyImage mit Grauwertbild
 */       
cMyImage *cMyImage::convertToGrayScale (void) {
    int width   = bmih.biWidth,
        height  = bmih.biHeight;
    int i, a, index;
    unsigned char *dummy = new unsigned char [imgsize];

    for (a = 0; a &lt; height; a++) {
        for (i = 0; i &lt; width; i++) {
            index = (a * width + i) * 3;
            dummy[index]   = (unsigned char)(0.56 * lpdata[index + indexR] + 0.11 * lpdata[index + indexG] + 0.33 * lpdata[index + indexB]);
            dummy[index + 1]  = dummy[index];
            dummy[index + 2]  = dummy[index];
        }
    }
    return new cMyImage(this-&gt;bmih, this-&gt;format, dummy);
}

/**
 * Filtern des Bildes
 * @return cMyImage mit gefiltertem Bild
 * @param op Filteroperator
 * @param opSize Größe des Operators (Seitenlänge)
 * @param flag Flags für den Filter. 
 * Mögliche Werte: 
 *      FIL_ABS - Absoluter Wert
 *      FIL_EQU - Normalisieren des Ergebnisses
 */
cMyImage *cMyImage::filter (int *op, int opSize, int flag) {
    int width   = bmih.biWidth,
        height  = bmih.biHeight;

    int a, i, sa, si, index, indexop;
    int d[3];
    unsigned char *dummy = new unsigned char [imgsize];
    memset (dummy, 0, imgsize);

    /* for each pixel */
    for (a = (opSize / 2); a &lt; height - (opSize / 2); a++) {
        for (i = (opSize / 2); i &lt; width - (opSize / 2); i++) {
            d[0] = 0;
            d[1] = 0;
            d[2] = 0;

            index = (a * width + i ) * 3;

            for (sa = 0; sa &lt; opSize; sa++) {
                for (si = 0; si &lt; opSize; si++) {
                    indexop = ((a + sa) * width + (i + si)) * 3;

                    d[indexR] += lpdata[indexop + indexR] * op[sa * opSize + si];
                    d[indexG] += lpdata[indexop + indexG] * op[sa * opSize + si];
                    d[indexB] += lpdata[indexop + indexB] * op[sa * opSize + si];
                }    
            }

            if (flag &amp; FIL_EQU) {
                d[indexR] /=  (opSize * opSize);
                d[indexG] /=  (opSize * opSize);
                d[indexB] /=  (opSize * opSize);
            }
            if (flag &amp; FIL_ABS) {
                 d[indexR] = abs(d[indexR]);  
                 d[indexG] = abs(d[indexG]);  
                 d[indexB] = abs(d[indexB]);  
            }

            dummy[index + indexR]     = d[indexR];
            dummy[index + indexG]     = d[indexG];
            dummy[index + indexB]     = d[indexB];
        }
    }
    return new cMyImage(this-&gt;bmih, this-&gt;format, dummy);
}

/**
 * Schwellwert für RGB festsetzen
 * @return cMyImage mit 0xffffff oder 0x000000 als Farbwerten
 */
cMyImage *cMyImage::trigger (unsigned char r, unsigned char g, unsigned char b)
{
    int width   = bmih.biWidth,
        height  = bmih.biHeight;
    int i, a, index;
    unsigned char *dummy = new unsigned char [imgsize];
    memset (dummy, 0, imgsize);

    for (a = 0; a &lt; height; a++) {
        for (i = 0; i &lt; width; i++) {
            index = (a * width + i) * 3;
            if (lpdata[index + indexR] &gt; r) {
                dummy[index + indexR]   =  0xff;
            }
            if (lpdata[index + indexG] &gt; g) {
                dummy[index + indexG]   =  0xff;
            }
            if (lpdata[index + indexB] &gt; b) {
                dummy[index + indexB]   =  0xff;
            }
        }
    }
    return new cMyImage(this-&gt;bmih, this-&gt;format, dummy);
}
/**
 * Ausdünnen der Linien 
 * @return cMyImage mit ausgedünnten Linien
 */
cMyImage *cMyImage::thin ()
{
    int width   = bmih.biWidth,
        height  = bmih.biHeight;
    int i, a, A, B, index;

    unsigned char *dummy = new unsigned char [imgsize];
    memset (dummy, 0, imgsize);

    for (a = 2; a &lt; height - 2; a++) {
        for (i = 2; i &lt; width - 2; i++) {
            index = (a * width + i) * 3;
            if (lpdata[index]) {
                A = calcBorders (i, a);
                B = calcNeighbours (i, a);

                if (
                        ((B &gt; 2 &amp;&amp; B &lt; 6) || B == 0 ) 
                    ||  (A == 1)
                    || (
                       (
                        (
                               (!lpdata[p2(i, a)]) 
                            &amp;&amp; (!lpdata[p4(i, a)]) 
                            &amp;&amp; (!lpdata[p8(i, a)])
                        ) 
                        || calcBorders(i, a -1) != 1
                        )
                    &amp;&amp; (
                        (
                               (!lpdata[p2(i, a)]) 
                            &amp;&amp; (!lpdata[p4(i, a)]) 
                            &amp;&amp; (!lpdata[p6(i, a)])
                        ) 
                        || calcBorders(i - 1, a) != 1
                       )
                      ) 
                   ) {
                    dummy [index] = 0;
                    dummy [index + 1] = 0;
                    dummy [index + 2] = 0;
                } else {
                    dummy [index] = lpdata[index];
                    dummy [index + 1] = lpdata[index + 1];
                    dummy [index + 2] = lpdata[index + 2];
                }
            } else {
                dummy [index] = lpdata[index];
                dummy [index + 1] = lpdata[index + 1];
                dummy [index + 2] = lpdata[index + 2];
            }
        }
    }
    return new cMyImage(this-&gt;bmih, this-&gt;format, dummy);
}

/**
 * Darstellen
 * @param hWnd Fenster auf das gemalt werden soll
 * @param x position x
 * @param y position y
 */
void cMyImage::blit (HDC hDC, int x, int y) {

    HDC     iDC = CreateCompatibleDC(hDC);

//	CopyMemory (d, lpdata, bmih.biSizeImage);
    SelectObject(iDC, DIBSec);

    BitBlt(hDC, x, y, this-&gt;bmih.biWidth, this-&gt;bmih.biHeight, iDC, 0, 0, SRCCOPY );

    DeleteDC(iDC);

}

/**
 * Speichern des Bildes in eine Datei
 * @param fileName - Dateiname
 */
/*
void cMyImage::saveBitmap(char *fileName) {
	// Save To Bitmap File
}
void  cMyImage::loadBitmap(char fileName) {

}
*/
/**
 * Anzahl Grenzfelder berechnen
 */
unsigned int cMyImage::calcBorders (int x, int y){
    int d = 0;
    if (lpdata[p2(x, y)] != 0 &amp;&amp; (0 == lpdata[p9(x, y)] ) ) d++;
    if (lpdata[p3(x, y)] != 0 &amp;&amp; (0 == lpdata[p2(x, y)] ) ) d++;
    if (lpdata[p4(x, y)] != 0 &amp;&amp; (0 == lpdata[p3(x, y)] ) ) d++;
    if (lpdata[p5(x, y)] != 0 &amp;&amp; (0 == lpdata[p4(x, y)] ) ) d++;
    if (lpdata[p6(x, y)] != 0 &amp;&amp; (0 == lpdata[p5(x, y)] ) ) d++;
    if (lpdata[p7(x, y)] != 0 &amp;&amp; (0 == lpdata[p6(x, y)] ) ) d++;
    if (lpdata[p8(x, y)] != 0 &amp;&amp; (0 == lpdata[p7(x, y)] ) ) d++;
    if (lpdata[p9(x, y)] != 0 &amp;&amp; (0 == lpdata[p8(x, y)] ) ) d++;

    return d;
}
/**
 * Anzahl Nachbarfelder berechnen
 */
unsigned int cMyImage::calcNeighbours (int x, int y)
{
    int d = 0;
    if (lpdata[p2(x, y)] != 0 ) d++;
    if (lpdata[p3(x, y)] != 0 ) d++;
    if (lpdata[p4(x, y)] != 0 ) d++;
    if (lpdata[p5(x, y)] != 0 ) d++;
    if (lpdata[p6(x, y)] != 0 ) d++;
    if (lpdata[p7(x, y)] != 0 ) d++;
    if (lpdata[p8(x, y)] != 0 ) d++;
    if (lpdata[p9(x, y)] != 0 ) d++;

    return d;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1277773</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277773</guid><dc:creator><![CDATA[DocJunioR]]></dc:creator><pubDate>Wed, 02 May 2007 17:49:43 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Wed, 02 May 2007 22:21:43 GMT]]></title><description><![CDATA[<p>Gorilla schrieb:</p>
<blockquote>
<p>1. Zunächst mal Gauss-Filter um gröbstes Rauschen zu eliminieren.</p>
</blockquote>
<p>soviel ich weiß ist es in dem fall besser 'nen medianfilter auf das bild anzuwenden, da bei 'nem unschärfefilter erstens die störungen nur verwischt werden und die energie im bild erhalten bleibt und zweitens - und das ist viel gravierender - auch die kanten mitgeschwächt werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1277867</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277867</guid><dc:creator><![CDATA[iko79]]></dc:creator><pubDate>Wed, 02 May 2007 22:21:43 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Thu, 03 May 2007 06:35:38 GMT]]></title><description><![CDATA[<p>Wie gesagt, das Vorgehen ist stark von der Bildqualität anhängig. Das gilt gerade für Rauschfilter.<br />
Im allgemeinen kommst du nicht drumherum Dich ein bisschen mit Buildverarbeitung zu beschäftigen UND zu probieren. Es giebt da -zig verschiedene Ansätze für ein und dasselbe Problem -&gt; schau doch mal im C++ - Magazin, da giebt es einen super Artikel zur Bildverarbeitung.</p>
<p>Um störende &quot;kleine&quot; Objekte zu entfernen dann am Ende eher morphologische Filter. Einfach gesagt, eine Art Sieb -&gt; kleine Objekte fallen Durch, große bleiben übrig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1277937</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277937</guid><dc:creator><![CDATA[TheBigW]]></dc:creator><pubDate>Thu, 03 May 2007 06:35:38 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Thu, 03 May 2007 07:18:16 GMT]]></title><description><![CDATA[<p>Wenn das Objekt wirklich elliptisch ist kannst Du's vielleicht auch mit ner Houghtransformation versuchen. Die hat den Vorteil, dass sie als integratives Verfahren sehr unempfindlich gegen Rauschen ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1277956</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1277956</guid><dc:creator><![CDATA[Jester]]></dc:creator><pubDate>Thu, 03 May 2007 07:18:16 GMT</pubDate></item><item><title><![CDATA[Reply to Kantenerkennug on Thu, 03 May 2007 18:30:53 GMT]]></title><description><![CDATA[<p>Vielen Dank für Eure Vorschläge,</p>
<p>der Gauss-Filter verwischt (wie Ihr schon geschrieben habt) tatsächlich auch die Kante. -Hab mal rumgelesen.<br />
Die Hough-Transformation ist laut meiner Bildverarbeitungsliteratur zu rechenintensiv für Zeitkritische Systeme (und das habe ich).<br />
Ich denke ich werde es mit Erosion und Dilatation probieren, da bleibt mir anscheinend die Kante erhalten und die Störenden Flecken verschwinden. -Ich bin mir nur unsicher ob das nicht auch sehr rechenintensiv ist???<br />
-Falls noch jamand eine Idee hat (-oder Quellcode) ...gerne.<br />
Danke nochmal<br />
Dom <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1278316</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1278316</guid><dc:creator><![CDATA[Gorilla]]></dc:creator><pubDate>Thu, 03 May 2007 18:30:53 GMT</pubDate></item></channel></rss>