HSV value of a color

Miscellaneous Forums/General Discussion/HSV value of a color

I'm trying to make a converted (that takes an image and adjusts its colors to a number of predefined colors, for ex. to convert an image to an old retro computer with a fixed 16-color palette). I *think* this is done by comparing the colorvalue of each image pixel with each colorvalue from the predefined list o' colors.

I figured HSV is better for this than RGB, however, how do you calc the 'value of a color' when you know H (0..359), S (0..1) and V (0..1) ?

And is this in general a good idea anyway?

http://www.blitzbasic.com/Community/posts.php?topic=62299#696245

It makes no difference whether you use RGB or HSV for color comparison. RGB is likely to be more precise.

hm.. I don't see the point of RGB here.

I have an array of hsv-locations, one for each color in my predefined list of colors.

Then I'll have the hsv-location of the pixel in an image, I iterate through the list of pre-defined colors, to see which one is the closest match.

I took HSV because I figured the HUE is quite an important factor, there's no such thing in RGB colorspace..

or do I miss something?

Well, that's one way of doing it. But you can do the same with rgb by selecting the color with the least variation.
variation_best = 100000
index_best = 0

For index = 0 Until palette_size
	variation_r = Abs(r - palette_r[index])
	variation_g = Abs(g - palette_g[index])
	variation_b = Abs(b - palette_b[index])
	variation_max = Max(variation_r,Max(variation_g,variation_b))
	If variation_max < variation_best
		index_best = index
		variation_best = variation_max
	EndIf
Next


Are you sure that works?? Don't have any sense making results here. While my source could be buggy (tho I've looked at it 4000 times by now), I don't quite see how it works by just reading your code.. :P

The variation comes from the colorcomponent with the largest error? The other two don't matter?

And wouldn't you want to know the smallest error instead?

Yes, it works.

If you know the palette color with the least maximal deviation from the original color, then you have the best match.

It's simply testing each palette index, and tests the maximal deviation from the original color, if it is less than the previous best match, then this palette index becomes the best match. It's not exactly rocket science :)

If you used the smallest deviation, you would get errors galore. Imagine this:
Palette[0] = 255 255 0
Palette[1] = 254 0 0
Color = 255 0 0
Using the least error would select palette index 0, which is clearly wrong.

ok, then I'm either blind, or too fubar as a result of twice working until 04:00 on a row :p

Exqueeze me for the bmax, I intended the topic to be only math-related, which is why I placed it in general. Tho, this code is quite generic.., could be readable by all.
SuperStrict
Local window:TGadget=CreateWindow("colorconverter",0,0,800,600)

Local canvas:TGadget=CreateCanvas(0,0,16*16,16*16,window)
Local canvas2:TGadget=CreateCanvas(300,0,16*16,16*16,window)

Local im:Int[16,16] ' <- original image, contains rgb data
Local im2:Int[16,16] ' <- destination image, will contain palette indexes

Local paletteR:Int[8]
Local paletteG:Int[8]
Local paletteB:Int[8]


' black red green blue yellow lightblue purple white
paletteR[1]=255
paletteG[2]=255
paletteB[3]=255

paletteR[4]=255
paletteG[5]=255
paletteB[6]=255

paletteG[4]=255
paletteB[5]=255
paletteR[6]=255

paletteR[7]=255
paletteG[7]=255
paletteB[7]=255


Local r:Int,g:Int,b:Int
Local t:Int
Local x:Int
Local y:Int


' create some pic
For y=0 To 15
	For x=0 To 15
		im[x,y]=(Limit(x*24,0,255))+256*Limit(y*24,0,255)+65536*Limit(128+Sin(y*70)*140,0,255)
	Next
Next


Local varbest:Int
Local indexbest:Int=10000
Local varr:Int,varg:Int,varb:Int,varmax:Int

For y=0 To 15
	For x=0 To 15
		' a pixel
		r=(im[x,y] Shr 16) & $ff
		g=(im[x,y] Shr  8) & $ff
		b=(im[x,y]       ) & $ff
	
		varbest=0
		indexbest=10000
		
		For t=0 To 7
			' a palette color
			varr=Abs(r-paletteR[t])
			varg=Abs(g-paletteG[t])
			varb=Abs(b-paletteB[t])
			
			varmax=Max(varr,Max(varg,varb))
			
			If varmax<varbest
			
				indexbest=t
				varbest=varmax
				
			EndIf
		Next
		
'		DebugLog indexbest
		indexbest=Min(indexbest,7)
		im2[x,y]=indexbest
	Next
Next


' update
SetCanvas canvas ' original image
	For y=0 To 15
		For x=0 To 15
			r=(im[x,y] Shr 16) & $ff
			g=(im[x,y] Shr  8) & $ff
			b=(im[x,y]       ) & $ff
			
			SetColor r,g,b
			DrawRect x*16,y*16,16,16
		Next	
	Next	
Flip

SetCanvas canvas2 ' newly built image
	For y=0 To 15
		For x=0 To 15
			r=paletteR[ im2[x,y] ]
			g=paletteG[ im2[x,y] ]
			b=paletteB[ im2[x,y] ]
			
			SetColor r,g,b
			DrawRect x*16,y*16,16,16
		Next	
	Next	
Flip


Repeat
	WaitEvent()
	If EventID()=EVENT_WINDOWCLOSE End
Forever


Function Limit:Int(v:Int,lo:Int,hi:Int)
	If v<lo Return lo
	If v>hi Return hi
	Return v
End Function

Function SetCanvas(c:TGadget)
	SetGraphics CanvasGraphics(c)
End Function


Don't mind the sloppyness of the structure, it's purely intended as quick hack to test it. If you must fix things: don't just replace whole chunks with own routiness, I wish to see thing fixed in my code.. :)

		varbest=10000
		indexbest=0
Not the opposite!

*aaargh*

ok.. early bed today, this is really getting out of hand now :P

btw, I'm not sure whether I follow all this math-voodoo, but as long as it works I'm not complaining. ^_^

As each R,G and B have different "intensity" values when for example converting a color image to a greyscale image I would suggest using different weights for each compoment.

Usual weights are like this:
intensity = 0.3*R + 0.59*G + 0.11*B

Try both methods, It would be nice to see what kind of difference you get.

I would attempt a CMYK conversion ONLY for printout and RGB is perfect for monitors... It is a standard:
http://dx.sheridan.com/advisor/cmyk_color.html

RGB is perfect for a monitor becausew the background is black (well it is black if nothing is lit... CMYK is perfect for paper as most printing is on WHITE paper...

http://www.december.com/html/spec/color16codes.html
Lists translations between codes...

http://www.kyb.tuebingen.mpg.de/events/colloquia/friko/ThomasWachtler.txt
An overstuffed reference that essentiqally says color apperception is affected by the colors neraby the color intended...

http://web.forret.com/tools/color.asp
ALl color codes I know of explained...

:)