bitmap különbség számítás, imagemagick

Fórumok

Keresem azt az imagemagick parancsot (és paramétereit), ami az A & B képből C-t allítja elő.
Két bitmap különbségét akarom kiszamítani, hogy ezzel spóroljak adatmennyiséget egy kliens-szerver rendszerben.

Meg is írtam hozzá az algoritmust, a vártnak megfelelően működik. PHP-ban számolom a külöbséget és JS-sel foltozom a C-t A-ra, megkapva így a B képet.
Viszont php-ban érezhetően lassabb a pixel számolás, mint célprogrammal.
Az imagemagick composite és compose kapcsolóit nézegettem, de pont ilyen transzformációt nem akart végezni.

Ha esetleg kész bináris programot vagy C kódrészletet tudtok rá, azt is szivesen fogadom.

A számítás lényege, hogy pixelenként és színcsatornánként különbséget számít és a többit rábízom a képformátum tömörítő algoritmusára. Kevés változtatás esetén sok lesz a fekete, ezért jó tömöríthetőséget várok.

Valószínűleg a kliens felén is javítani kell, mert a pixelenként canvasra rajzolás elég lassúnak tűnik.

kép A.

kép B.

kép C.

Hozzászólások

composite sxl36ik.png jmhkBHv.png -compose difference diff.png
532 byte

Szerk, mégse ez kell.

Szerk II: A példaképek biztos jók? Pl. az 0. oszlop 2. sor-ban eltérnek a színek, mégis feketét rajzoltál.

Mindenesetre:
convert jmhkBHv.png sxl36ik.png -compose Subtract -composite diff.png
convert sxl36ik.png diff.png -compose Add -composite test.png

Amúgy segítene, ha megmondanád, hogy milyen algoritmust keresel, mert sima különbségnél pl. gond nélkül lesz probléma az unsigned típus miatt. A legbiztosabb szerintem ha olyan képet küldesz ki, amiben azt írod le, hogy hol változott valami és az új értéket küldöd (convert jmhkBHv.png sxl36ik.png -compose Difference -composite -threshold 0 sxl36ik.png -compose Multiply -composite test.png), de akkor meg a kliens nem tudja, hogy a fekete az a "nem változott" vagy "feketévé változott"-at jelenti-e. Az alpha csatornán van hasznos információ?

Szerk III: a zárójeles hosszú kifejezés helyett biztosabb a -compose ChangeMask -composite arra, amit írtam.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

a [0,2] mező nem teljesen fekete hanem #000100 színű.
először én is úgy gondoltam h két pixel közti különbség csak kétszer akkora helyen férhet el, mert
első kép -> második kép
0 -> 255 => 255-0=255
255 -> 0 => 0-255=-255
-255..255 intervallumban kellene tárolni egy pixel egy csatornájának a különbségét, ami 2 byte.
viszont az fogadó félnek megvan az első kép és annak ismeretében elég a különbség 1 byte-ra eső részét közölni vele. egyszerűen hagyni kell tulcsordulni a byte-ban tárolt értékeket.
ezért az algoritmusom így néz ki pszeudókóddal:

különbség képzés:


  max[r]=max[g]=max[b]=256
  max[a]=128  (valamiért az alphát csak 7 biten tárolja)
  img_diff[x,y,chan] = img_b[x,y,chan] - img_a[x,y,chan]
  if img_diff[x,y,chan] < 0 then img_diff[x,y,chan] += max[chan]

összeadás:


  b = img_a[x,y,chan] + img_diff[x,y,chan]
  if b >= max[chan] then b -= max[chan]
  img_b[x,y,chan] = b

így lesz az hogy a [0,2] mező
A: #ffff00
B: #ff0000
r -> ff - ff = 00
g -> 00 - ff = -ff = 01 (underflow)
b -> 00 - 00 = 00
C: #000100

összeadás a g csatornára:
ff + 01 = 0100 = 00 (overflow)

~~~~~~~~
deb http://deb.metaltux.tk/ wheezy yazzy repack

Aha... így már értem. Akkor első körben a ModulusSubtract (http://www.imagemagick.org/Usage/compose/#modulus_subtract) kell neked, az alfa csatornával való küzdést viszont most feladtam (három soros convert utasításnál tartok, de eddig nem sikerült rávennem, hogy az alpha csatornát 0...127-en számítsa).

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

nekem jobb lenne ha az alpha is 8 bites lenne, akkor nem kéne erre is egy-egy elágazás a kódban :)
csak azt figyeltem meg h a php image* függvényei 127-et adnak vissza gimpben szerkesztett kép tökig átlátszó pixeljére.

~~~~~~~~
deb http://deb.metaltux.tk/ wheezy yazzy repack

a neve és a leírása alapján tényleg ez kell de nekem szemre ugyan olyan képet generál a Subtract és a ModulusSubtract is! :O

... helyesbítek, (composite A B -compose ModulusSubtract C)-t hívtam (composite B A -compose ModulusSubtract C) helyett, tehát az A és B-t fordított sorrendben kell megadni. így már nagyon hasonló képet generál mint én, viszont ModulusAdd-dal a lenti képet kapom vissza, nem a B-t.

ellenben a magam kódja által generált C képet ModuludAdd-dal összeadva az A-val szépen kijön a B kép (alpha értékektől eltekintve).

(composite B A -compose ModulusSubtract C)

(composite A C -compose ModulusAdd B2)

~~~~~~~~
deb http://deb.metaltux.tk/ wheezy yazzy repack

nekem a compose subtract és compose add műveletsor nem a B képet eredményezte hanem egy A-hoz hasonló képet.

screenshot-okról van szó és a képek forrása PPM formátumú, amiben plaintext-ként is olvasható és hirtelen úgy tűnik, nincs benne alpha információ. lehet h kesőbb teljesen el is hagyom.

illetőleg még kipróbalom a különbségszámítást az eredeti PPM fájlokon, annak gyorsabbnak kell legyen. mert most a már kigenerált PNG-ken végeztem a kivonást, ami imagemagick-kel <1 sec, de php-ban 8..10

~~~~~~~~
deb http://deb.metaltux.tk/ wheezy yazzy repack

az a jelenlegi megoldásom, hogy nem kivonom a képeket, hanem XOR kapun tolom át!
a tömöríthetőség kérdésébe nem merültem bele, de az azonos pixelek itt is feketék lesznek.

az imagemagick parancs:


  convert -evaluate-sequence xor A B C

plusz előny hogy ugyanígy lehet C-ből és A-ból megkapni B-t.

a kliensoldali lassúságot betudom a presto motornak, mert webkit-en csakúgy süvít :D

~~~~~~~~
deb http://deb.metaltux.tk/ wheezy yazzy repack