Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Ausschnitt in Bild finden
paul_94
myCSharp.de - Member



Dabei seit:
Beiträge: 1
Herkunft: Bayern

Themenstarter:

Ausschnitt in Bild finden

beantworten | zitieren | melden

Beschreibung:
Hi,

ich habe eine Klasse erstellt welche in einem großen Bild ein kleineres Bild sucht.
Gibt es warscheinlich schon mehrere aber ich dachte ich beglücke euch einfach mal mit meinem Code.

Von meinen C# Künsten her würde ich mich etwas höher als Anfänger einordnen.

Das Bild wird vorher in eine List<List<Color>> umgewandeln um auf zu viele getPixel aufrufe zu verzichten, da diese wohl recht langsam zu sein scheinen.

Vllt sollte ich aber von den Listen weg gehen und zu Arrays wechseln, das diese glaube noch schneller sind.

Über verbesserungsvorschläge würde ich mich freuen :D

Die methode "findPictureCoords" gibt die linke obere Ecke des teilbilds als Point auf dem Bild in dem gesucht wurde zurück.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace findMeinBild
{
    class findPicture
    {
        private Image searchIn;
        private List<List<Color>> list_searchIn;
        private List<List<Color>> list_searchedFor;
        private List <Point> maybe_points=new List<Point>();
        private List<int> hits_list = new List<int>();

        public findPicture(Image searchIn)
        {
            this.searchIn = searchIn;
            list_searchIn = imageToList(searchIn);
        }

        public Point findPictureCoords(Image searchedFor)
        {
            list_searchedFor = imageToList(searchedFor);
            int allPixels = searchedFor.Width * searchedFor.Height;
            
            if (searchIn.Size.Width > searchedFor.Width && searchIn.Height > searchedFor.Size.Height)
            {
                for (int line = 0; line < searchIn.Height - searchedFor.Height; line++)
                {
                    for (int col = 0; col < searchIn.Width - searchedFor.Width; col++)
                    {
                        if (list_searchIn[col][line] == list_searchedFor[0][0] && list_searchIn[col+searchedFor.Width-1][line] == list_searchedFor[searchedFor.Width-1][0])
                        {
                            maybe_points.Add(new Point(col,line));
                            int hits = 0;
                            for (int y = 0; y < searchedFor.Height; y++)
                            {
                                for (int x = 0; x < searchedFor.Width; x++)
                                {
                                    if (list_searchIn[x + col][y + line] == list_searchedFor[x][y])
                                    {
                                        hits++;
                                    }
                                }
                            }
                            hits_list.Add(hits);
                        }
                    }
                }
            }

            int highest=0;
            int i=0;
            while (i < hits_list.Count - 1)
            {
                if (hits_list[i] > highest)
                {
                    highest = i;
                }
                i++;
            }

            if (maybe_points[0] != null)
            {
                return maybe_points[highest];
            }
            else
            {
                return new Point(-1, -1);
            }
        }

        public List<List<Color>> imageToList(Image img)
        {
            List<List<Color>> pixelList = new List<List<Color>>();
            Bitmap bmp_pixels=new Bitmap(img);
            for (int col = 0; col < img.Width; col++)
            {
                List<Color> lines = new List<Color>();
                for (int line = 0; line < img.Height; line++)
                {
                    lines.Add(bmp_pixels.GetPixel(col,line));
                }
                pixelList.Add(lines);
            }
            return pixelList;
        }
    }
}

Verwenden tut man die Klasse folgendermaßen:


picfind = new findPicture(BILDINDEMGESUCHTWIRD);
point p = picfind.findPictureCoords(BILDAUSSCHNITT)
ps.: Wenn jemand diesen Code in seinem Projekt verwenden möchte und kein Geld damit verdient, kann er das gerne machen.
Ich möchte aber bitte informiert werden und ein Credit eintrag tut mir auch nicht weh :D

Schlagwörter: findPicture, bild finden, button finden,
Dieser Beitrag wurde 6 mal editiert, zum letzten Mal von paul_94 am .
if (brain != null)
{
BoardSearch.use(question);
}
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo paul_94,

üblicherweise würde man zum schnellen Zugriff auf die Bitmap-Daten direkt oder indirekt Bitmap.LockBits und BitmapData.Stride verwenden. Siehe auch GetPixel und SetPixel um Längen geschlagen. 800 mal schneller.

herbivore
private Nachricht | Beiträge des Benutzers
Tomot
myCSharp.de - Member

Avatar #avatar-2678.jpg


Dabei seit:
Beiträge: 706
Herkunft: Düsseldorf

beantworten | zitieren | melden

[offtopic]
@paul_94: Je nachdem was du vor hast, könntest du dir auch mal SIFT-Features angucken. Die sind nämlich rotations- und skalierunsinvariant.
[/offtopic]
mit freundlichen Grüßen,
Tomot

Projekte: www.gesellschaftsspieler-gesucht.de
private Nachricht | Beiträge des Benutzers