 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 26.02.2010, 19:17 Titel: [Geloest]RGBToIndex |
|
|
Ich hab seit einigen Wochen mal wieder einj kleines Projekt angefangen und hab ein ziemlichen haenger...
Ich braeuchte mal dringenden Rat zu moeglichkeiten und methoden um RGB Bilder in 256 Indexfarben yu berechnen...
Hab schon die 3-3-2bits variante durch und diverse varianten die auf anyahl farben und helligkeitswerte basieren, mit eher maessigem erfolg, meine vorstellung ist eine 'optimierte#n indexierung wie eine umwandlung mit einem grafikprogramm, farben und bild sollen eben so aenhlich wie moeglich am original sein.
Ziel soll spaeter sein ein 24/32bit Image in eine 8bit GIF zu speichern...
gruss
Edit:
Hat 'ne weile gedauert den Algo zu verstehen aber ist nun abgehakt... _________________

Zuletzt bearbeitet von Eternal_pain am 06.03.2010, 11:15, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 26.02.2010, 19:50 Titel: |
|
|
möchtest du so ne musterung dabei bekommen wie das bei paint passiert zB, wenn die farbe nicht so sonderlich gut approximiert werden konnte?
so wie die graue fläche hier: http://www.iupui.edu/~webtrain/images/tutorial_images/ppt_custom_color_scheme.gif
wenn man genau hin sieht merkt man dass das dunkelgrau und hellgrau gemustert ist, und nicht einheitliches mittelgrau _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 26.02.2010, 19:59 Titel: |
|
|
verlink halt wenigstens den englischen.. 200x umfangreicher as usual
http://en.wikipedia.org/wiki/Dither _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 27.02.2010, 00:40 Titel: |
|
|
An Dithering hab ich eher nicht gedacht, ywar kann man damit unter umstaenden wohl sicherlich gute ergebnisse erziehlen, hab meine 'Handarbeiten' bisher aber im Grafikprogramm ohne Dithering reduziert... ich guck mal ob ichs irgendwie schaff mal was aufs notebook zu ziehen um ein paar meiner versuche zu zeigen die ungefaehr wohl klar machen was und wie ichs vor hatte, denke jedoch das es dafuer sowas wie eine 'PATENTLOESUNG' gibt... sowas wie eine einheitliche berechnung... bit der 3-3-2 methode bekomme ich kein besonders ansehnliches ergebniss, da wird bspw ein bild mit weit ueber 800000 farben ueberwiegend blautoenen zu 85 indexfarben reduziert die uebergaenge sind schlicht zu hart... _________________
 |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 27.02.2010, 02:57 Titel: |
|
|
FreeImage hat jede Menge Konvertierungsfunktionen mit an Bord. Ein Versuch wäre es bestimmt wert. |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 27.02.2010, 14:15 Titel: |
|
|
Hi, ich denke FreeImage kann das sicherlich, ist aber nicht das was ich will, ich moechte schlicht keine anderen libs nutzen, haette mich sonst nicht ewig mit LZW und LZ77 kompressionen rumgeschlagen
hier is mal einer meiner ansaetze.. sieht prinzipiel auf den ersten blick ganz gut aus, was die uebergaenge angeht allerdings sind die farben leicht verfaelscht.....
Code: |
Function ColorCount (byval Image as any ptr) as UInteger
If Image=0 Then Return 0
Dim BufferVersion as UInteger=Peek(UInteger,Image)
If BufferVersion<>7 Then Return 0
Dim BufferBPP as UInteger=Peek(UInteger,Image+4)
Dim BufferSizeX as UInteger=Peek(UInteger,Image+8)
Dim BufferSizeY as UInteger=Peek(UInteger,Image+12)
Dim BufferPitch as UInteger=Peek(UInteger,Image+16)
Dim ColorBitList as UByte ptr=Callocate(2097152)
Dim CBLByte as UInteger
Dim CBLBit as UByte
Dim IndexColor as UInteger
Dim CountColor as UInteger
For Y as UInteger=0 to BufferSizeY-1
For X as UInteger=0 to BufferSizeX-1
Select Case as Const BufferBPP
Case 1
IndexColor=Peek (Ubyte ,Image+32+(X*BufferBPP)+(Y*BufferPitch))
Case 2
IndexColor=Peek (UShort ,Image+32+(X*BufferBPP)+(Y*BufferPitch))
Case Else
IndexColor=Peek (UInteger ,Image+32+(X*BufferBPP)+(Y*BufferPitch)) and &h00FFFFFF
End Select
CBLByte = Fix(IndexColor/8)
CBLBit = (IndexColor mod 8)
If Bit(ColorBitList[CBLByte],CBLBit)=0 Then
CountColor+=1
ColorBitList[CBLByte]+=(1 SHL CBLBit)
End If
Next X
Next Y
Deallocate (ColorBitList)
Return CountColor
End Function
Sub RGBToIndex (Byref Image as any ptr)
If Image=0 Then Exit Sub
Dim ImageVersion as UInteger=Peek(UInteger,Image)
If ImageVersion <> &h07 Then Exit Sub
Dim ImageBPP as UInteger=Peek(UInteger,Image+4)
If ImageBPP < &h03 Then Exit Sub
Dim Imagewidth as UInteger=Peek(UInteger,Image+8)
Dim Imageheight as UInteger=Peek(UInteger,Image+12)
Dim Imagepitch as UInteger=Peek(UInteger,Image+16)
'Step1
Dim ReadColor as UInteger
Dim IndexMap as UInteger PTR=Callocate(16)
Dim IndexBitMap as UByte Ptr Ptr=Callocate(16)
IndexBitMap[0]=Callocate(24)
IndexBitMap[1]=Callocate(24)
IndexBitMap[2]=Callocate(24)
IndexBitMap[3]=Callocate(24)
Dim IBMByte as Integer
Dim IBMBit as Integer
Dim RRed as Integer
Dim RGreen as Integer
Dim RBlue as Integer
Dim RH as Integer
For Y as UInteger=0 to Imageheight-1
For X as UInteger=0 to Imagewidth-1
ReadColor=Peek(UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch))
RRed = Lobyte(Hiword(ReadColor))
RGreen = Hibyte(Loword(ReadColor))
RBlue = Lobyte(Loword(ReadColor))
RH = (RRed+RGreen+RBlue)/3
If RH>31 and RH<224 Then
RH=IIF(RH-64 < 0,0,RH-64)
IBMByte = Fix(RH/8)
IBMBit = (RH mod 8)
If RRed > RGreen and RRed >= RGreen Then
If Bit(IndexBitMap[0][IBMByte],IBMBit)=0 Then
IndexMap[0]+=1
IndexBitMap[0][IBMByte]+=(1 SHL IBMBit)
End If
ElseIf RGreen > RBlue and RGreen >= RRed Then
If Bit(IndexBitMap[1][IBMByte],IBMBit)=0 Then
IndexMap[1]+=1
IndexBitMap[1][IBMByte]+=(1 SHL IBMBit)
End If
ElseIf RBlue > RRed and RBlue >= RGreen Then
If Bit(IndexBitMap[2][IBMByte],IBMBit)=0 Then
IndexMap[2]+=1
IndexBitMap[2][IBMByte]+=(1 SHL IBMBit)
End If
ElseIf RRed = RGreen and RGreen = RBlue Then
If Bit(IndexBitMap[3][IBMByte],IBMBit)=0 Then
IndexMap[3]+=1
IndexBitMap[3][IBMByte]+=(1 SHL IBMBit)
End If
End If
End If
Next X
Next Y
Dim IBMCRed as UByte Ptr=Callocate(192)
Dim IBMCRedC as UByte
Dim IBMCGreen as UByte Ptr=Callocate(192)
Dim IBMCGreenC as UByte
Dim IBMCBlue as UByte Ptr=Callocate(192)
Dim IBMCBlueC as UByte
Dim IBMCGrey as UByte Ptr=Callocate(192)
Dim IBMCGreyC as UByte
For IBMC as UInteger=0 to 191
IBMByte = Fix(IBMC/8)
IBMBit = (IBMC mod 8)
IBMCRed[IBMC] =IBMCRedC
IBMCGreen[IBMC]=IBMCGreenC
IBMCBlue[IBMC] =IBMCBlueC
IBMCGrey[IBMC] =IBMCGreyC
If Bit(IndexBitMap[0][IBMByte],IBMBit) Then IBMCRedC += 1
If Bit(IndexBitMap[1][IBMByte],IBMBit) Then IBMCGreenC += 1
If Bit(IndexBitMap[2][IBMByte],IBMBit) Then IBMCBlueC += 1
If Bit(IndexBitMap[3][IBMByte],IBMBit) Then IBMCGreyC += 1
Next IBMC
Deallocate (IndexBitMap[3])
Deallocate (IndexBitMap[2])
Deallocate (IndexBitMap[1])
Deallocate (IndexBitMap[0])
Deallocate (IndexBitMap)
Dim IndexPMap as Double=(IndexMap[0]+IndexMap[1]+IndexMap[2]+IndexMap[3])/254
Dim IndexPRed as Integer=1
Dim IndexPGreen as Integer=IndexPRed + (IndexMap[0]/IndexPMap)
Dim IndexPBlue as Integer=IndexPGreen + (IndexMap[1]/IndexPMap)
Dim IndexPGrey as Integer=IndexPBlue + (IndexMap[2]/IndexPMap)
'?IndexPRed,IndexMap[0],191/IndexMap[0]/IndexPMap
'?IndexPGreen,IndexMap[1],IndexMap[1]/IndexPMap
'?IndexPBlue,IndexMap[2],IndexMap[2]/IndexPMap
'?IndexPGrey,IndexMap[3],IndexMap[3]/IndexPMap
'Step2
Dim HighColorMap as Ubyte PTR=Callocate(2097152)
Dim IndexColorMap as UByte PTR=Callocate(32)
Dim HCMByte as Integer
Dim HCMBit as Integer
Dim ICMByte as Integer
Dim ICMBit as Integer
Dim PrePal as UInteger Ptr=Callocate(256*4)
Dim Index as Integer
Dim MRed as Integer
Dim MGreen as Integer
Dim MBlue as Integer
Dim WriteColor as UInteger
For Y as UInteger=0 to Imageheight-1
For X as Uinteger=0 to Imagewidth-1
ReadColor=Peek(UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch)) and &h00FFFFFF
HCMByte =Fix(ReadColor/8)
HCMBit =(ReadColor mod 8)
RRed = Lobyte(Hiword(ReadColor))
RGreen = Hibyte(Loword(ReadColor))
RBlue = Lobyte(Loword(ReadColor))
RH = (RRed+RGreen+RBlue)/3
If Bit(HighColorMap[HCMByte],HCMBit)=0 Then
HighColorMap[HCMByte]+=(1 SHL HCMBit)
' If RH<128 Then
' RRed = IIF(RRed -5 < 0, 0, RRed -5)
' RGreen = IIF(RGreen -5 < 0, 0, RGreen -5)
' RBlue = IIF(RBlue -5 < 0, 0, RBlue -5)
' Else
' RRed = IIF(RRed +5 > 255, 255, RRed +5)
' RGreen = IIF(RGreen +5 > 255, 255, RGreen +5)
' RBlue = IIF(RBlue +5 > 255, 255, RBlue +5)
' End If
WriteColor=RGB(RRed,RGreen,RBlue)
If RH>31 and RH<224 Then
RH=IIF(RH-64 < 0,0,RH-64)
If RRed>RGreen and RRed >=RBlue Then
Index=IndexPRed + (IBMCRed[RH] / (IBMCRedC/(IndexMap[0]/IndexPMap)))
RRed = IIF(RRed +10 > 255, 255, RRed +10)
If RRed=RBlue Then RBlue = IIF(RBlue +10 > 255, 255, RBlue +10)
ElseIf RGreen>RBlue and RGreen>=RRed Then
Index=IndexPGreen + (IBMCGreen[RH] / (IBMCGreenC/(IndexMap[1]/IndexPMap)))
RGreen = IIF(RGreen +10 > 255, 255, RGreen +10)
If RGreen=RRed Then RRed = IIF(RRed +10 > 255, 255, RRed +10)
ElseIf RBlue>RRed and RBlue>=RGreen Then
Index=IndexPBlue + (IBMCBlue[RH] / (IBMCBlueC/(IndexMap[2]/IndexPMap)))
RBlue = IIF(RBlue +10 > 255, 255, RBlue +10)
If RBlue=RGreen Then RGreen = IIF(RGreen +10 > 255, 255, RGreen +10)
ElseIf RRed=RGreen and RGreen=RBlue Then
Index=IndexPGrey + (IBMCGrey[RH] / (IBMCGreyC/(IndexMap[3]/IndexPMap)))
End If
Else
Index=IIF(RH<32,0,255)
End If
ICMByte=Fix(Index/8)
ICMBit =(Index mod 8)
If Bit(IndexColorMap[ICMByte],ICMBit)=0 Then
IndexColorMap[ICMByte]+=(1 SHL ICMBit)
If Index>0 and Index<255 Then
PrePal[Index]=WriteColor
Else
PrePal[Index]=RGB(Index,Index,Index)
End If
Else
MRed = Lobyte(Hiword(PrePal[Index]))
MGreen = Hibyte(Loword(PrePal[Index]))
MBlue = Lobyte(Loword(PrePal[Index]))
PrePal[Index]=RGB( ((RRed+MRed)/2), ((RGreen+MGreen)/2), ((RBlue+MBlue)/2))
End If
End If
Next X
Next Y
'Step3
For Y as UInteger=0 to Imageheight-1
For X as Uinteger=0 to Imagewidth-1
ReadColor=Peek(UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch))
RRed = Lobyte(Hiword(ReadColor))
RGreen = Hibyte(Loword(ReadColor))
RBlue = Lobyte(Loword(ReadColor))
RH = (RRed+RGreen+RBlue)/3
If RH>31 and RH<224 Then
RH=IIF(RH-64 < 0,0,RH-64)
If RRed>RGreen and RRed >=RBlue Then
Index=IndexPRed + (IBMCRed[RH] / (IBMCRedC/(IndexMap[0]/IndexPMap)))
ElseIf RGreen>RBlue and RGreen>=RRed Then
Index=IndexPGreen + (IBMCGreen[RH] / (IBMCGreenC/(IndexMap[1]/IndexPMap)))
ElseIf RBlue>RRed and RBlue>=RGreen Then
Index=IndexPBlue + (IBMCBlue[RH] / (IBMCBlueC/(IndexMap[2]/IndexPMap)))
ElseIf RRed=RGreen and RGreen=RBlue Then
Index=IndexPGrey + (IBMCGrey[RH] / (IBMCGreyC/(IndexMap[3]/IndexPMap)))
End If
Else
Index=IIF(RH<32,0,255)
End If
Poke UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch),PrePal[Index]
Next X
Next Y
Put (0,0),image
/'
dim cx as integer
dim cy as integer
for l as integer=0 to 255
line (341+(cx*20),1+(cy*20))-(359+(cx*20),19+(cy*20)),PrePal[l],bf
'If l>=IndexPRed and l<IndexPGreen Then
'or l=IndexPGreen or l=IndexPBlue or l=IndexPGrey Then
' line (340+(cx*20),0+(cy*20))-(360+(cx*20),20+(cy*20)),&hFFFFFF,b
'End if
cx+=1
If cx=16 then cx=0:cy+=1
next l
'/
End Sub
#Include "[Function]TextureLoad.bi"
Screen 19,32
Dim Test as any ptr
Test=TextureLoad("universe.bmp")
RGBToIndex(Test)
'Put (0,0),test
?ColorCount(Test)
sleep
|
textureload einfach duch laden einer bitmap ersetzen _________________
 |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 01.03.2010, 07:01 Titel: |
|
|
weiss evtl jemand ein paar links zu diesem Thema?
Da die meisten Grafikprogramme diese Funktion haben muesste es doch irgendwo auch eine brauchbare referenz dafuer geben, habe mit google bisher leider noch nichts brauchbares gefunden... _________________
 |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 01.03.2010, 14:41 Titel: |
|
|
Schau doch einfach in den Freeimage Sourcecode, und lass dich ... inspirieren  |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 03.03.2010, 13:11 Titel: |
|
|
nach ewigen Googlen und Lesen und leider wenig verstehen der Unterschiedlichsten Farbmodelle und Algorithmen hab ich endlich ansatzweise gefunden was ich suchte....
Hier koennte ich ein wenig Hilfe bei der uebersetzung gebrauchen da ich leider nicht alles ganz verstehe...
Der Code ist java...
Hier noch ein paar hilfreiche erklaerende links zur Theorie des Themas
http://www.it.fht-esslingen.de/~schmidt/vorlesungen/mm/seminar/ss00/HTML/node200.html
http://en.literateprograms.org/Median_cut_algorithm_(C_Plus_Plus)
Code: |
package ij.process;
import java.awt.*;
import java.awt.image.*;
import ij.*; //??
/** Converts an RGB image to 8-bit index color using Heckbert's median-cut
color quantization algorithm. Based on median.c by Anton Kruger from the
September, 1994 issue of Dr. Dobbs Journal.
*/
public class MedianCut {
static final int MAXCOLORS = 256; // maximum # of output colors
static final int HSIZE = 32768; // size of image histogram
private int[] hist; // RGB histogram and reverse color lookup table
private int[] histPtr; // points to colors in "hist"
private Cube[] list; // list of cubes
private int[] pixels32;
private int width, height;
private IndexColorModel cm;
public MedianCut(int[] pixels, int width, int height) {
int color16;
pixels32 = pixels;
this.width = width;
this.height = height;
//build 32x32x32 RGB histogram
IJ.showProgress(0.3);
IJ.showStatus("Building 32x32x32 RGB histogram");
hist = new int[HSIZE];
for (int i=0; i<width*height; i++) {
color16 = rgb(pixels32[i]);
hist[color16]++;
}
}
public MedianCut(ColorProcessor ip) {
this((int[])ip.getPixels(), ip.getWidth(), ip.getHeight());
}
int getColorCount() {
int count = 0;
for (int i=0; i<HSIZE; i++)
if (hist[i]>0) count++;
return count;
}
Color getModalColor() {
int max=0;
int c = 0;
for (int i=0; i<HSIZE; i++)
if (hist[i]>max) {
max = hist[i];
c = i;
}
return new Color(red(c), green(c), blue(c));
}
// Convert from 24-bit to 15-bit color
private final int rgb(int c) {
int r = (c&0xf80000)>>19;
int g = (c&0xf800)>>6;
int b = (c&0xf8)<<7;
return b | g | r;
}
// Get red component of a 15-bit color
private final int red(int x) {
return (x&31)<<3;
}
// Get green component of a 15-bit color
private final int green(int x) {
return (x>>2)&0xf8;
}
// Get blue component of a 15-bit color
private final int blue(int x) {
return (x>>7)&0xf8;
}
/** Uses Heckbert's median-cut algorithm to divide the color space defined by
"hist" into "maxcubes" cubes. The centroids (average value) of each cube
are are used to create a color table. "hist" is then updated to function
as an inverse color map that is used to generate an 8-bit image. */
public Image convert(int maxcubes) {
ImageProcessor ip = convertToByte(maxcubes);
return ip.createImage();
}
/** This is a version of convert that returns a ByteProcessor. */
public ImageProcessor convertToByte(int maxcubes) {
int lr, lg, lb;
int i, median, color;
int count;
int k, level, ncubes, splitpos;
int num, width;
int longdim=0; //longest dimension of cube
Cube cube, cubeA, cubeB;
// Create initial cube
IJ.showStatus("Median cut");
list = new Cube[MAXCOLORS];
histPtr = new int[HSIZE];
ncubes = 0;
cube = new Cube();
for (i=0,color=0; i<=HSIZE-1; i++) {
if (hist[i] != 0) {
histPtr[color++] = i;
cube.count = cube.count + hist[i];
}
}
cube.lower = 0; cube.upper = color-1;
cube.level = 0;
Shrink(cube);
list[ncubes++] = cube;
//Main loop
while (ncubes < maxcubes) {
// Search the list of cubes for next cube to split, the lowest level cube
level = 255; splitpos = -1;
for (k=0; k<=ncubes-1; k++) {
if (list[k].lower == list[k].upper)
; // single color; cannot be split
else if (list[k].level < level) {
level = list[k].level;
splitpos = k;
}
}
if (splitpos == -1) // no more cubes to split
break;
// Find longest dimension of this cube
cube = list[splitpos];
lr = cube.rmax - cube.rmin;
lg = cube.gmax - cube.gmin;
lb = cube.bmax - cube.bmin;
if (lr >= lg && lr >= lb) longdim = 0;
if (lg >= lr && lg >= lb) longdim = 1;
if (lb >= lr && lb >= lg) longdim = 2;
// Sort along "longdim"
reorderColors(histPtr, cube.lower, cube.upper, longdim);
quickSort(histPtr, cube.lower, cube.upper);
restoreColorOrder(histPtr, cube.lower, cube.upper, longdim);
// Find median
count = 0;
for (i=cube.lower;i<=cube.upper-1;i++) {
if (count >= cube.count/2) break;
color = histPtr[i];
count = count + hist[color];
}
median = i;
// Now split "cube" at the median and add the two new
// cubes to the list of cubes.
cubeA = new Cube();
cubeA.lower = cube.lower;
cubeA.upper = median-1;
cubeA.count = count;
cubeA.level = cube.level + 1;
Shrink(cubeA);
list[splitpos] = cubeA; // add in old slot
cubeB = new Cube();
cubeB.lower = median;
cubeB.upper = cube.upper;
cubeB.count = cube.count - count;
cubeB.level = cube.level + 1;
Shrink(cubeB);
list[ncubes++] = cubeB; // add in new slot */
if (ncubes%15==0)
IJ.showProgress(0.3 + (0.6*ncubes)/maxcubes);
}
// We have enough cubes, or we have split all we can. Now
// compute the color map, the inverse color map, and return
// an 8-bit image.
IJ.showProgress(0.9);
makeInverseMap(hist, ncubes);
IJ.showProgress(0.95);
return makeImage();
}
void Shrink(Cube cube) {
// Encloses "cube" with a tight-fitting cube by updating the
// (rmin,gmin,bmin) and (rmax,gmax,bmax) members of "cube".
int r, g, b;
int color;
int rmin, rmax, gmin, gmax, bmin, bmax;
rmin = 255; rmax = 0;
gmin = 255; gmax = 0;
bmin = 255; bmax = 0;
for (int i=cube.lower; i<=cube.upper; i++) {
color = histPtr[i];
r = red(color);
g = green(color);
b = blue(color);
if (r > rmax) rmax = r;
if (r < rmin) rmin = r;
if (g > gmax) gmax = g;
if (g < gmin) gmin = g;
if (b > bmax) bmax = b;
if (b < bmin) bmin = b;
}
cube.rmin = rmin; cube.rmax = rmax;
cube.gmin = gmin; cube.gmax = gmax;
cube.bmin = bmin; cube.bmax = bmax;
}
void makeInverseMap(int[] hist, int ncubes) {
// For each cube in the list of cubes, computes the centroid
// (average value) of the colors enclosed by that cube, and
// then loads the centroids in the color map. Next loads
// "hist" with indices into the color map
int r, g, b;
int color;
float rsum, gsum, bsum;
Cube cube;
byte[] rLUT = new byte[256];
byte[] gLUT = new byte[256];
byte[] bLUT = new byte[256];
IJ.showStatus("Making inverse map");
for (int k=0; k<=ncubes-1; k++) {
cube = list[k];
rsum = gsum = bsum = (float)0.0;
for (int i=cube.lower; i<=cube.upper; i++) {
color = histPtr[i];
r = red(color);
rsum += (float)r*(float)hist[color];
g = green(color);
gsum += (float)g*(float)hist[color];
b = blue(color);
bsum += (float)b*(float)hist[color];
}
// Update the color map
r = (int)(rsum/(float)cube.count);
g = (int)(gsum/(float)cube.count);
b = (int)(bsum/(float)cube.count);
if (r==248 && g==248 && b==248)
r=g=b=255; // Restore white (255,255,255)
rLUT[k] = (byte)r;
gLUT[k] = (byte)g;
bLUT[k] = (byte)b;
}
cm = new IndexColorModel(8, ncubes, rLUT, gLUT, bLUT);
// For each color in each cube, load the corre-
// sponding slot in "hist" with the centroid of the cube.
for (int k=0; k<=ncubes-1; k++) {
cube = list[k];
for (int i=cube.lower; i<=cube.upper; i++) {
color = histPtr[i];
hist[color] = k;
}
}
}
void reorderColors(int[] a, int lo, int hi, int longDim) {
// Change the ordering of the 5-bit colors in each word of int[]
// so we can sort on the 'longDim' color
int c, r, g, b;
switch (longDim) {
case 0: //red
for (int i=lo; i<=hi; i++) {
c = a[i];
r = c & 31;
a[i] = (r<<10) | (c>>5);
}
break;
case 1: //green
for (int i=lo; i<=hi; i++) {
c = a[i];
r = c & 31;
g = (c>>5) & 31;
b = c>>10;
a[i] = (g<<10) | (b<<5) | r;
}
break;
case 2: //blue; already in the needed order
break;
}
}
void restoreColorOrder(int[] a, int lo, int hi, int longDim) {
// Restore the 5-bit colors to the original order
int c, r, g, b;
switch (longDim){
case 0: //red
for (int i=lo; i<=hi; i++) {
c = a[i];
r = c >> 10;
a[i] = ((c&1023)<<5) | r;
}
break;
case 1: //green
for (int i=lo; i<=hi; i++) {
c = a[i];
r = c & 31;
g = c>>10;
b = (c>>5) & 31;
a[i] = (b<<10) | (g<<5) | r;
}
break;
case 2: //blue
break;
}
}
void quickSort(int a[], int lo0, int hi0) {
// Based on the QuickSort method by James Gosling from Sun's SortDemo applet
int lo = lo0;
int hi = hi0;
int mid, t;
if ( hi0 > lo0) {
mid = a[ ( lo0 + hi0 ) / 2 ];
while( lo <= hi ) {
while( ( lo < hi0 ) && ( a[lo] < mid ) )
++lo;
while( ( hi > lo0 ) && ( a[hi] > mid ) )
--hi;
if( lo <= hi ) {
t = a[lo];
a[lo] = a[hi];
a[hi] = t;
++lo;
--hi;
}
}
if( lo0 < hi )
quickSort( a, lo0, hi );
if( lo < hi0 )
quickSort( a, lo, hi0 );
}
}
ImageProcessor makeImage() {
// Generate 8-bit image
Image img8;
byte[] pixels8;
int color16;
IJ.showStatus("Creating 8-bit image");
pixels8 = new byte[width*height];
for (int i=0; i<width*height; i++) {
color16 = rgb(pixels32[i]);
pixels8[i] = (byte)hist[color16];
}
ImageProcessor ip = new ByteProcessor(width, height, pixels8, cm);
IJ.showProgress(1.0);
return ip;
}
} //class MedianCut
class Cube { // structure for a cube in color space
int lower; // one corner's index in histogram
int upper; // another corner's index in histogram
int count; // cube's histogram count
int level; // cube's level
int rmin, rmax;
int gmin, gmax;
int bmin, bmax;
Cube() {
count = 0;
}
public String toString() {
String s = "lower=" + lower + " upper=" + upper;
s = s + " count=" + count + " level=" + level;
s = s + " rmin=" + rmin + " rmax=" + rmax;
s = s + " gmin=" + gmin + " gmax=" + gmax;
s = s + " bmin=" + bmin + " bmax=" + bmax;
return s;
}
}
|
_________________
 |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|