NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Porovnání několika pixelů

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Ladislav Krejcí:7.5.2017 22:18

Ahoj, dělám program na řízení gravírovačky na DPS.. funguje to na principu toho že z obrázku se vyberou všechny černé pixely, které se uloží do

List<string>

chtěl bych mít možnost používat více nástrojů (fréz), ale nedaří se mi napsat funkci která nástrojům různých velikostí nastavila různé pozice tzn. že velké plochy by se dělali velkým nástrojem a malé plochy malým nástrojem.
zkoušel jsem to dělat pomocí funkce

List<string> matching = toollist.Intersect(list).ToList();

kdy toollist je určitý počet pixelu podle toho jak je nástroj velký a list jsou všechny černý pixely
pokud nebyl např 6x6 pixelů žádný černý pixel tak se zapsal do .txt, ale bohužel mě tato funkce nefungovala správně vždy to zapsalo pozici o 6 více tzn. 1x1, 1x7,1x13 atd..

předem děkuji za všechny rady

 
Odpovědět
7.5.2017 22:18
Avatar
Radek Chalupa:7.5.2017 22:45

Nevím zda jsem jediný kdo nechápe na co se ptáš...? Možná proto že nevím (a nehledal jsem to) co je to "gravírovačka". Nicméně z programátorského pohledu nechápu jak (resp. hlavně proč) ukládáš pixely do stringu? A s čím se mají porovnávat?

 
Nahoru Odpovědět
7.5.2017 22:45
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na Ladislav Krejcí
ostrozan:8.5.2017 8:18

To je pravda, proč string?
Asi bys to měl blíž popsat - to procházíš nějakou bitmapu ?
A dobrý by byl nějaký konkrétní kód.

 
Nahoru Odpovědět
8.5.2017 8:18
Avatar
Ladislav Krejcí:8.5.2017 8:33

Proč string je to jednoduché int "123123" string "123, 123"... vyzkouším to vysvětlit trošku jinak mám obrázek kde jsou černé a bílé pixely získám pozice všech černých pixelu a potom bych potřeboval plochy které budou obsahovat třeba 6x6, 3x3 a 1x1 tzn že se postupně bude posouvat 1x1 poslední pozice 6x6 a pokud v těchto pixelech a na konci vsechny souradnice srovna s zicema černých pixelů a pokud v každé té skupině najde jeden černý pixel tak se odstraní poté se to stejné z opakuje s 3x3 a 1x1 kdy se bude porovnavat s černou a všemi předchozími tzn 6x6... 3x3

 
Nahoru Odpovědět
8.5.2017 8:33
Avatar
Ladislav Krejcí:9.5.2017 13:21

asi jste mě stále nepochopili.. černá barva je část která se nebude měnit a bílá část se bude odstraňovat pomocí frézy.. chci aby byla možnost použití různých fréz dle tloušťky "mezery" bíle pixely získávám z bitmap

 Bitmap schematic = new Bitmap;
List<string> Pos_blc= new List<string>()
schematic = pic_box.image;
//hledání černých pixelu je uděláno pomocí funkce for
Color pixelColor = myBitmap.GetPixel(50, 50);
if(pixelColor.R <=200 && pixelColor.G <=200 && pixelColor.B <=200 )
{
//tímto způsobem získám bíle pixely včetně tmavších odstínu a zapíšu jako list string
Pos_blc.add(pos_x +","+ pos_y)
}

a teď přichází problém... pokud by se tato funkce ovládala jen pomocí pixelů musel bych použít malý nástroj a gravírování by trvalo dlouho takže bych potřeboval nějakou funkci který by byla schopná najít nějaké společné pixely na tloušťku nástroje viz obrázek..

 
Nahoru Odpovědět
9.5.2017 13:21
Avatar
Honza
Člen
Avatar
Odpovídá na Ladislav Krejcí
Honza:9.5.2017 13:56

Řešil bych to asi tak, že bych procházel bitmapu a ve chvíli kdy bych narazil na bílý pixel, prohledal bych jeho okolí abych zjistil jestli tam je další, nebo jestli je osamocený. Pokud by tam byl další tak bych prohledal i jeho okolí a tak pořád dokola, dokud bych nenarazil na černou barvu. Určitě bych to ale nedával do pole stringů, protože s tím se pak nedá rozumě pracovat. Nechal bych to v bitmapě a někam bych připojil informací o tom, jaký nástroj se má kde použít. Nebo by šlo vytvořit nějakou vlastní strukturu, do které by sis ukládal informace získané z bitmapy. V podstatě by tam šlo ukládat jednotlivé "tahy". Tzn. souřadnice počátku, souřadnice konce a typ použitého nástroje. Možností je vždycky celá řada.

Nahoru Odpovědět
9.5.2017 13:56
Snadnou cestou se daleko nedostanete, je tam velká tlačenice...
Avatar
Odpovídá na Honza
Ladislav Krejcí:9.5.2017 16:03

Ještě jsem si to prošel a asi to udělám pomocí vertikalnich a horizontálních cest kdyby to vzalo třeba souradnici 1x20 - 40 a našlo by to stejné v dalších osach tzn.. 2x20 - 40 3x20 - 40 atd... dokud by to nenašlo černý pixel až budu mít k dispozici pc tak něco udělám a pochlubim se... jinak ten string jsem změnil na float protože jsem potřeboval desetiny

 
Nahoru Odpovědět
9.5.2017 16:03
Avatar
Ladislav Krejcí:9.5.2017 21:02

vyzkoušel jsem napsat program který zjištuje stejné pozice pixelu ve sloupci, ale vypíše se asi 3-5 řádku a zbytek jsou samé nuly nevím proč zkoušel jsem kontrolovat zdroják ale nic jsem nenašel

for (int a = 1; bitmapHeight > a; a++)
           {

               if (xPos[x] == b)
               {
                   y1[x1] = yPos[x];
                   x1++;
                   x++;



               }
               else if(xPos[x] == (b + 1))
               {
                   y2[x1] = yPos[x];
                   x++;
                   x1++;

               }
               else
               {
                 for(int i = 0; i < y1.Length; i++)
                   {
                       for(int j = 0; j < y2.Length; j++)
                       {
                           if(y1[i] == y2[j])
                           {
                               if(y1[i] > 1)
                               {
                                   value_lenght++;
                                   value[value_lenght] = y1[i];
                               }

                           }
                       }
                   }
                   x1 = 0;
                   b++;

               }
           }
           string[] result = value.Select(h => h.ToString()).ToArray();
           System.IO.File.WriteAllLines("c:\\files.gcode", result );
Editováno 9.5.2017 21:04
 
Nahoru Odpovědět
9.5.2017 21:02
Avatar
Odpovídá na Ladislav Krejcí
Radek Chalupa:9.5.2017 22:34

Pokud jde o rychlost tak bych v žádném případě nepoužíval GetPixel, ale LockBits a pak procházet pixely pomocí pointeru. Vytvářet novou instanci třídy Color pro každý pixel, kterých jsou v běžné bitmapě stovky, bude násobně pomalejší než prostě skočit přes pointer na další pixel (adresu) a dereferencí přečíst příslušné hodnoty RGB.

 
Nahoru Odpovědět
9.5.2017 22:34
Avatar
Ladislav Krejcí:10.5.2017 1:04

nemyslím rychlost programu ale rychlost ovládaného stroje...

 
Nahoru Odpovědět
10.5.2017 1:04
Avatar
Odpovídá na Radek Chalupa
Marian Benčat:10.5.2017 10:55

Dobrý point, ale tady nejsme v low levlu, ale v C# a managed kodu, zmiňovat pointery a dereferenci, je tedy zde dosti mimo mísu.

Nahoru Odpovědět
10.5.2017 10:55
Totalitní admini..
Avatar
Odpovídá na Marian Benčat
Radek Chalupa:10.5.2017 11:04

Tohle je funkce pro převod fotky na stupně šedé, a schválně si to zkus udělat tak že budeš vyzobávat jednotlivé pixely pomocí GetPixel a následně zapisovat pomocí SetPixel. A změř si časy pro nějakou větší fotku a uvidíš co je mimo mísu....

public static void PrevodNaStupne­Sede(ref Bitmap bitmap)
{
if (bitmap == null)
throw new NullReference­Exception();
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bitmapData = bitmap.LockBit­s(rect, ImageLockMode­.ReadWrite, PixelFormat.For­mat32bppArgb);
unsafe
{
byte* pData = (byte)(void)bit­mapData.Scan0;
int delka = (bitmapData.Height * bitmapData.Width * 4);
byte* pKonec = pData + delka;
byte b;
while (pData < pKonec)
{
b = (byte)(((11 * ((pData + 2)) + 59 * ((pData + 1)) + 30 * (*(pData)))) / 100);
*(pData + 3) = 255;
*pData = b;
*(pData + 1) = b;
*(pData + 2) = b;
pData += 4;
}
}
bitmap.UnlockBit­s(bitmapData);
}

 
Nahoru Odpovědět
10.5.2017 11:04
Avatar
Odpovídá na Marian Benčat
Luboš Běhounek Satik:10.5.2017 11:20

Zrovna v tomhle případě souhlasím s Radkem, přes pointer je to o celý řád rychlejší než přes GetPixel().
Proto se i v C# celkem běžně pro rychlou práci s bitmapama (kde potřebuješ řešit jednotlivý pixely) používají pointery přes unsafe, takže je fuk, jestli jsme v managed kódu nebo ne a mimo mísu to rozhodně není.

Jinak co se detekce týče, jak přesně pak zadáváš vstupy pro to gravírování? Jako seznam bodů a jejich velikostí? Nebo můžeš i zadávat linie?

Nahoru Odpovědět
10.5.2017 11:20
https://www.facebook.com/peasantsandcastles/
Avatar
Luboš Běhounek Satik:10.5.2017 11:31

Jestli je to jen zadávání bodů, tak je to vlastně hledání co největších vepsaných kružnic, to bych asi procházel všechny bílý pixely a zjišťoval, jak velkou kružnici tam můžu udělat, aby pořád ještě pokrývala jen bílou barvu a pak bych asi začal od těch největších a přidal je do seznamu pro gravírování a přepočítal bych ty kružnice, který to ovlivnilo (abys třeba nepálil některý pixely dvakrát).

Nahoru Odpovědět
10.5.2017 11:31
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Radek Chalupa
Marian Benčat:10.5.2017 12:48

OK, dostal jsem vyškolíno.

Nahoru Odpovědět
10.5.2017 12:48
Totalitní admini..
Avatar
Odpovídá na Luboš Běhounek Satik
Ladislav Krejcí:10.5.2017 18:17

abyhc řekl pravdu tak programovat jsem se učil z internetu pomocí vyhledávání tagu.. takže moc nevím jak takovou funkci udělat předpokládám že vezmu nějaký pixel a zjistím jakou barvu mají pixely kolem pak do každého směru přidám pixel a udělám to stejné dokud nenarazím na černý pixel... tento nápad se mi líbí ale moje mozková kapacita nedosahuje toho aby jsem program napsal správně :D

 
Nahoru Odpovědět
10.5.2017 18:17
Avatar
HONZ4
Člen
Avatar
Odpovídá na Ladislav Krejcí
HONZ4:10.5.2017 18:33

ono asi bude záležet na tom, jakým způsobem se pohybuje gravírovací hlava a jaký tvar a rozměr má gravírovací nástroj. A podle toho, zvolit nejvhodnější způsob detekce.

Editováno 10.5.2017 18:36
 
Nahoru Odpovědět
10.5.2017 18:33
Avatar
Odpovídá na HONZ4
Ladislav Krejcí:10.5.2017 19:04

myslím si že je hloupost předem definovat rozměr nástroje to pak pro to udělám nějakou matiku.. myslím si že nejlepší by bylo aby se pohybovala po rádcích

 
Nahoru Odpovědět
10.5.2017 19:04
Avatar
HONZ4
Člen
Avatar
Odpovídá na Ladislav Krejcí
HONZ4:10.5.2017 20:31

pokud nemáš definovanou "šířku" nástroje tak nechápu proč detekovat bílé body v okolí (navíc pokud se chceš pohybovat po řádcích)? Nebo ta gravírka si volí nástroje nějak automaticky? Aby Ti mohl někdo pomoct budeš to muset trochu víc popsat, hlavně to jaký potřebuješ ideální výstup. Podle zdejších reakcí asi nejsem jediný, kdo vůbec nechápe co vlastně potřebuješ...

Editováno 10.5.2017 20:33
 
Nahoru Odpovědět
10.5.2017 20:31
Avatar
Ladislav Krejcí:13.5.2017 19:12

dneska jsem si sedl a dodělal jsem funkci... nakonec jsem to udělal tak že bude jeden nástroj (červená barva v obrázku) která jezdí středem mezery.. teď jen dodělat generování posunu os a program má zařízený kompletní pohyb... zdroják

 
Nahoru Odpovědět
13.5.2017 19:12
Avatar
Ladislav Krejcí:15.5.2017 22:12

snad už poslední dotaz... dneska jsem si hrál s programem a zkoušel jsem různá schemata a generovat cesty pro gravirovačku, ale některé cesty jsou přerušené viz. obrázek... jak by jste to řešili ? jediné co mě napadlo je že by to hledalo bílá místa kolem pixelů a snažilo je to dokreslit třeba v okruhu dvacet pixelu... samozřejmě s nějakou logikou aby se program snažil generovat trasy podle předlohy předchozích pixelu..

 
Nahoru Odpovědět
15.5.2017 22:12
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 21 zpráv z 21.