[c++ Builder] wykrywanie białych plam

0

Czy ktoś by mógł mi przybliżyć sposób na wykrywanie białych plam obraznie czarno-białym (odcienie szarości) 8-bitowym obrazie BMP. Z góry dzięki za wszelkie pomysły wskazówki.

0

przejedź po pikselach obrazka za pomocą ScanLine, i sprawdzaj:

if (piksel==clWhite)
{
//tu na przykład zapisuj współrzędne piksela w jakiejś tablicy
}
0

jednak zrobiłem bez scanaline: każdą wartość piksela koloru białego zamieniam na inny kolor. Czemu tak jest ze na jednym obrazie dobrze zamienia a na drugim biały kolor zmieniony jest na inny, ale tez mieści się w 8-bitach szarości?

0

Przedstaw swój kod, to zobaczymy :)

0
    int R;
    TColor k;

    for(int x=0;x<Image2->Picture->Bitmap->Width;x++)
    {
        for(int y=0;y<Image2->Picture->Bitmap->Height;y++)
        {
            k = Image2->Picture->Bitmap->Canvas->Pixels[x][y];
            R=GetRValue(k);
 
            if (R == clWhite)
            {
                R == clRed; 
                Image2->Picture->Bitmap->Canvas->Pixels[x][y]= R;
            }
            else
                Image2->Picture->Bitmap->Canvas->Pixels[x][y]= R;
        }
    }

wiem że to taki prostacki sposób no ale :) Może trzeba poprzesuwać jakoś bity w obrazie - nie wiem
Powodzenia

0

Zamiast porównywać do nasycenia koloru czerwonego, porównuj do całego koloru:

TColor k;
     for(int x=0;x<Image2->Picture->Bitmap->Width;x++)
     for(int y=0;y<Image2->Picture->Bitmap->Height;y++)
     {
            k = Image2->Picture->Bitmap->Canvas->Pixels[x][y];
            Image2->Picture->Bitmap->Canvas->Pixels[x][y]=(k==clWhite) ? clRed : k;
      }
0

no niestety jest tak samo

0

Spróbuj jeszcze na początku przekąwertować bitmapę na 24-bitową:

 
Image2->Picture->Bitmap->PixelFormat =pf24bit;

Innych pomysłów nie mam!

0

no to gratuluje świetnego pomysłu działa :)
A może powiesz czemu to działa ?

0

Zapewne wcześniej białe plamy były zamieniane na jakiś tam odcień szarości, ponieważ cała bitmapa mogła się składać tylko z takich. Dlatego wystarczyło przestawić z monochromatycznej na pełno kolorową (24bity=3bajty - czerwony, zielony, niebieski). Wcześniej czerwonego koloru piksel nie miał prawa uzyskać - dlatego.

Więcej na ten temat dowiesz się tu

0

Najwydajniejszym rozwiązaniem, za to troszke skomplikowanym byłoby odczytanie pliku BMP jako pliku binarnego, przeszukanie paletyw celu w odnalezienia indexu koloru białego i znalezienie tegoż koloru w danych obrazowych.

0
Gosc napisał(a)

Najwydajniejszym rozwiązaniem, za to troszke skomplikowanym byłoby odczytanie pliku BMP jako pliku binarnego, przeszukanie paletyw celu w odnalezienia indexu koloru białego i znalezienie tegoż koloru w danych obrazowych.

Lepszym, ale nie najlepszym. Tym sposobem trzebaby czytać polik z dysku, co spowalnia proces, lub wczytywać plik do pamięci 2 razy. Najlepszym sposobem byłaby funkcja ScanLine:

TColor k;
Bitmapa->PixelFormat =pf24bit; //Ustawiam format pixeli na 24 bitowy
for ( unsigned y = 0; y<Bitmapa->Height; y++)
        {
        char* p = (char*)Bitmapa->ScanLine[y];
        for ( unsigned x = 0; x<Bitmapa->Width; x++)
            {
             k=p[x];
             p[x]=(k==clWhite) ? clRed : k;
             }
         }
0

Jest prostszy sposób. Nie trzeba sie bawić w czytanie pikseli. Wystarczy ustawić własność bitmapy TransparentColor na biały i namalować ją czerwonym prostokącie.

0
adf88 napisał(a)

Jest prostszy sposób. Nie trzeba sie bawić w czytanie pikseli. Wystarczy ustawić własność bitmapy TransparentColor na biały i namalować ją czerwonym prostokącie.

taaa, a po zapisaniu obrazka bitmapa będzie taka sama. Aleś pomysłowy!

0

Ale ja przepraszam, czegoś nie rozumiem... czy my mówimy o 8-bitowym obrazie bmp? takim z paletą? Takim z paletą, która dla każdego koloru definiuje składowe rgb, a później dane obrazu zawierają tylko indeksy kolorów?

No ale jakie Scanline, jakie czytanie pikseli, panowie...

  • otworzyć jako binarny
  • skoczyć w offset 0x36, załadować paletę do tablicy char colors[256][3]
  • znaleźć indeks, dla którego r,g,b ==255. Zmienić r,g,b na taką wartość, jaką się chce
  • i zapisać paletę z powrotem (a co tam paletę! 3 bajty zapisać, te które się zmieniło!).
0

W BITMAPINFO są 4 bajty na kolor, tamto z 3 było chyba win 3.1, z 40 lat temu.

char* p = (char*)Bitmapa->ScanLine[y];
for ( unsigned x = 0; x<Bitmapa->Width; x++)
    {
       k=p[x];
       p[x]=(k==clWhite) ? clRed : k;
    }

wstawiłeś 3 bajty na kolor to musisz skakać co 3: x += 3,

k = p[x]; // jeden bajt
warunek:
k == clWhite będzie zawsze fałszywy, bo clWhite = 0xffffff, a k <= 0xff

jeśli nawet mogłoby to działać to po co to k?
if( p[x] == clWhite ) p[x] = clRed;

</cpp>
0
JaskMar napisał(a)
adf88 napisał(a)

Jest prostszy sposób. Nie trzeba sie bawić w czytanie pikseli. Wystarczy ustawić własność bitmapy TransparentColor na biały i namalować ją czerwonym prostokącie.

taaa, a po zapisaniu obrazka bitmapa będzie taka sama. Aleś pomysłowy!

taaa, a po zapisaniu tego co namalowaliśmy będzie co potrzba. Aleś bystry !
Z utworzeniem nowej palety też dobry pomysł. Ale nie zapomnij, najpierw trzeba konwertować z 8 bitów bez palety na 24bity z paletą.

0
Ranides napisał(a)

Ale ja przepraszam, czegoś nie rozumiem... czy my mówimy o 8-bitowym obrazie bmp? takim z paletą? Takim z paletą, która dla każdego koloru definiuje składowe rgb, a później dane obrazu zawierają tylko indeksy kolorów?

No ale jakie Scanline, jakie czytanie pikseli, panowie...

  • otworzyć jako binarny
  • skoczyć w offset 0x36, załadować paletę do tablicy char colors[256][3]
  • znaleźć indeks, dla którego r,g,b ==255. Zmienić r,g,b na taką wartość, jaką się chce
  • i zapisać paletę z powrotem (a co tam paletę! 3 bajty zapisać, te które się zmieniło!).

Coś Ci się pomyliło- w bitmapie 8-bitowej monochromatycznej nie mamy składowych RGB. Trzeba ją przekonwertować, na 24- bitową, która takie indeksy już posiada. A to w trybie binarnym nie byłoby już takie proste.

badzo napisał(a)

W BITMAPINFO są 4 bajty na kolor, tamto z 3 było chyba win 3.1, z 40 lat temu.

Można sobie to przestawić, żeby było łatwiej.

0
JaskMar napisał(a)

Coś Ci się pomyliło- w bitmapie 8-bitowej monochromatycznej nie mamy składowych RGB. Trzeba ją przekonwertować, na 24- bitową, która takie indeksy już posiada. A to w trybie binarnym nie byłoby już takie proste.

Jeszcze się nie spotkałem, z takim czymś jak 8 bitowa bitmapa monochromatyczna, albo 24 bitowa posiadająca paletę. Jeżeli bitmapa jest 8 bitowa, musi zawierać paletę.
Nie mniej polecam się zapoznać z formatem BMP, zamiast pisać takie bzdury.
Sposób Ranides'a jest najlepszym i najszybszym rozwiązaniem.

0
Gość napisał(a)

Jeszcze się nie spotkałem, z takim czymś jak 8 bitowa bitmapa monochromatyczna, albo 24 bitowa posiadająca paletę. Jeżeli bitmapa jest 8 bitowa, musi zawierać paletę.
Nie mniej polecam się zapoznać z formatem BMP, zamiast pisać takie bzdury.
Sposób Ranides'a jest najlepszym i najszybszym rozwiązaniem.

Składowe RGB to nie jest to samo co paleta kolorów! Istnieje zarówno bitmapa 8-bitowa, która posiada 256 różnych kolorów, jak i taka, która ma 256 odcieni szarości. A to, że nie spotkałeś się z 24-bitową, posiadającą paletę kolorów - to dopiero bzdura!

Zwracam honor w jednej sprawie - pomyliła mi się monochromatyczna (czyli dwukolorowa) z odcieniami szarości.

0
JaskMar napisał(a)

A to, że nie spotkałeś się z 24-bitową, posiadającą paletę kolorów - to dopiero bzdura!

Tylko powiedz po co paleta w bitmapie 24 bitowej? :>

0
0x666 napisał(a)
JaskMar napisał(a)

A to, że nie spotkałeś się z 24-bitową, posiadającą paletę kolorów - to dopiero bzdura!

Tylko powiedz po co paleta w bitmapie 24 bitowej? :>

Np. paleta 2^24 kolorów formatu R32G32B32 :-P

0
adf88 napisał(a)
0x666 napisał(a)
JaskMar napisał(a)

A to, że nie spotkałeś się z 24-bitową, posiadającą paletę kolorów - to dopiero bzdura!

Tylko powiedz po co paleta w bitmapie 24 bitowej? :>

Np. paleta 2^24 kolorów formatu R32G32B32 :-P

Rozmawiajmy o standardzie BMP, a nie jakiś egzotycznych odmianach. Jak wcześniej powtórzyłem polecam się zapoznać ze standardem BMP, a szczególnie fragmentem dot. palety: http://en.wikipedia.org/wiki/Windows_and_OS/2_bitmap#Color_palette

0
Gosc napisał(a)
adf88 napisał(a)

Np. paleta 2^24 kolorów formatu R32G32B32 :-P

Rozmawiajmy o standardzie BMP, a nie jakiś egzotycznych odmianach.

Hehe przecież to był żart. Wystarczy sobie policzyć ile taka paleta ważyłaby dla całej 24-bitowej gamy kolorów ;-)

0

Przecież ta paleta nie jest zapisywana w pliku. Liczy ona sobie 224 kolorów, czyli tyle, ile jest w stanie wyświetlić zwykły monitor. W pliku jest tylko zapisane, że właśnie takiej palety się używa. To wszystko.

0

Przecież to nielogiczne. Taka paleta ważyłaby ~50MB, a 24-bitowy indeks miałby tą samą wartość co kolor w palecie, na który wskazuje.

0

Dokładnie 48MB :-p , ale wyobraź sobie, że zamiast zapisywać paletę, można zapisać prosty algorytm, który dowolny dowolny kolor znajdzie. W Borlandowskoch IDE taki algorytm kryje się pod funkcją RGB(). Powtarzam - kolory, składające się z indeksów RGB, gdzie każdy z nich przyjmuje wartości 0-255, to również konkretna paleta kolorów.

Przecież można by wymyślić paletę, która dla RGB przyjmowałaby wartości 0-65536. A że większość monitorów nie będzie w stanie jej wyświetlić - jego strata

0
JaskMar napisał(a)

W Borlandowskoch IDE taki algorytm kryje się pod funkcją RGB().

:-D To NIE jest funkcja tylko makro z pliku wingdi.h:

#define RGB(r,g,b)          ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
JaskMar napisał(a)

Powtarzam - kolory, składające się z indeksów RGB, gdzie każdy z nich przyjmuje wartości 0-255, to również konkretna paleta kolorów.

Po pierwsze, to nie są indeksy tylko odcienie poszczególnych składowych koloru. Po drugie zaczynasz kombinować - mówimy tu o palecie jako tablicy z możliwymi kolorami, a nie o tym, że RGB może opisywać pewną paletę kolorów (z określoną rozdzielczością).

W 24 bitowych bitmapach piksel opisany jest w 3 bajtach, które zawierają info o intensywności składowych R, G i B. Żadne tam indeksy [!!!]

0

JaskMar: dyskusje na modłę greckich filozofów moglibyśmy do usranej śmierci prowadzić. Zamiast więc tworzyć jakieś wyimaginowane wizje, wziąłem bitmapę 480x360, zamieniłem na grayscale i sprawdziłem rozmiar pliku (bo więcej mi się nie chciało).

Rozmiar pliku rzeczywisty: 173 878
Z czego:
172 800 danych obrazu
1 078 danych nagłówkowych

Jak nagłówek zajmuje ponad KB, to oczywiste, że jest tam chyba "coś" więcej, niż sygnatura pliku :] Owe "coś", to nie zgadniesz: paleta zajmująca 1024 bajty. Zostaje 54 bajty. I znowu niespodzianka:
podpina się to pod wzór dla bitmapy z paletą:

user image
gdzie n to ilość bitów na piksel (n=8).

A co do twoich wywodów:
tak, wiesz, ja sobie mogę stworzyć "bitmapę" co będzie miała 5 kanałów w dwóch bajtach:
2: R
3: G
2: B
1: przeźroczystość
8: położenie na osi Z

i co z tego? Po cholerę coś wymyślasz? Takich dziwactw nie ma. To już nie standardowa bitmapa. To twoje własne widzimisię i nikomu nie wmówisz, że jest inaczej. Nie ma co kombinować, tylko powiedzieć jasno, że się machnąłeś.

Też się machnąłem, bo z pamięci rzuciłem, że mamy 3 bajty na kolor, a domyślnie przypada 4 bajty (ten czwarty nieużywany zazwyczaj).

IMHO EOT, bo w następnych postach mogę się co najwyżej powtarzać - tutaj zostało empirycznie pokazane, że nie ma takich cudów, jak grayscalowa bitmapa bez palety.

0

Jak zwał, tak zwał, może i nie indeksy, tylko odcienie, a może nasycenie... kij wie, to tylko nazwa.
Co za różnica, czy makro, czy funkcja. Równie dobrze to makro można przedstawić w postaci funkcji.

A po drugie - każdy plik BMP ma paletę. Tylko niektóre z nich mają ją zapisaną w pliku całą (PixelFormat=pfCostum), a inne, które posługują się paletami standardowymi, jak np. 24 bity, RGB, lub 1 bit biało-czarny, mają tylko zapisany stan flagi PixelFormat:
pf1bit
pf4bit
pf8bit
pf15bit
pf16bit
pf24bit
pf32bit

A i machnąłem się. Przez pierwszy post w tym temacie. Ale upieram się - bitmapa 24-bitowa ma paletę, tylko nie zapisaną w pliku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1