[comp.graphics] help with quick color map search

rosenbl@cis.ohio-state.edu (Robert Rosenblum) (10/20/89)

I'm writing an application which involves taking a given rgb value and
finding the color in the color map which is closest.  My routine
performs a linear search through the color map, comparing the
"distance" between my rgb value and each color map entry, and the
index of the closest color is returned.  However, this technique is
very slow.

Is there is a more efficient way to find the closest color in a color
map?  Any help would be greatly appreciated.


  Thanks in advance.....

      Rob Rosenblum



Rob Rosenblum                  
The Ohio State University      
Department of Computer and Information Science
2036 Neil Ave. Columbus OH USA 43210-1277
rosenbl@cis.ohio-state.edu 
  or ...!osu-cis!cis.ohio-state.edu!rosenbl

erichs@microsoft.UUCP (Erich Stehr) (10/20/89)

In article <67563@tut.cis.ohio-state.edu> rosenbl@cis.ohio-state.edu (Robert Rosenblum) writes:
>My routine
>performs a linear search through the color map, comparing the
>"distance" between my rgb value and each color map entry, and the
>index of the closest color is returned.  However, this technique is
>very slow.

Are you doing a square root for each iteration?  If you are, that's
one of your problems.  All you need is the relative "distance" between 
the colors, and the squares of the distances will have the same relative
ordering.

Erich Stehr	"The Sorceress' Apprentice"	uunet!microsoft!erichs

bdb@becker.UUCP (Bruce Becker) (10/21/89)

In article <67563@tut.cis.ohio-state.edu> rosenbl@cis.ohio-state.edu (Robert Rosenblum) writes:
|I'm writing an application which involves taking a given rgb value and
|finding the color in the color map which is closest.  My routine
|performs a linear search through the color map, comparing the
|"distance" between my rgb value and each color map entry, and the
|index of the closest color is returned.  However, this technique is
|very slow.
|
|Is there is a more efficient way to find the closest color in a color
|map?  Any help would be greatly appreciated.

	I needed to do this some time ago, so I'll try
	to remember roughly what I did.

	First, form an octree from the available color
	palette such that each cell contains a single color.
	This is done by inserting cells into the tree and
	subdividing when a target cell is already occupied.
	Once this is done the test rgb value is test-inserted
	into the octree, and compared in distance to the
	target cell contents and all adjacent neighbors.
	The worst case # of distance measurements is 27, but
	usually it is far less.

	A useful variant is to convert rgb to a form which
	expresses hue saturation and value in orthogonal axes.
	(HSV as usually implemented does NOT meet this
	criterion). One way to do this is to convert to
	Yxy CIE form, and produce hue & saturation values by:

		x = xc - xw
		y = yc - yw

		hue = arctan(y/x) (0.0 if x == 0.0)
			    2    2
		sat = sqrt(x  + y )

	Where xc,yc are the CIE color values and xw,yw
	are for the reference white. YIQ values can be
	used for the conversion without much problem to
	the end result.

	If the octree and the test color are expressed in
	these terms such that the relative weighting of
	the distance function is something like 4:2:1 for
	normalized brightness:hue:saturation values, then
	it is possible to get better matches from a visual
	point of view, especially when the reference palette
	is limited or has a poor perceptual distribution.

	Remember that this is off the top of my head from
	work done some years ago; your mileage may vary;
	contents have certainly settled during shipment;
	etc...

Cheers,
-- 
  ....	 Bruce Becker	Toronto, Ont.
w \**/	 Internet: bdb@becker.UUCP, bruce@gpu.utcs.toronto.edu
 `/C/-e	 BitNet:   BECKER@HUMBER.BITNET
_/  >_	 "But... but.. reality isn't *real*..." - Pippy the Zkinhead

kensy@microsoft.UUCP (Ken Sykes) (10/21/89)

In article <8126@microsoft.UUCP> erichs@microsoft.UUCP (Erich Stehr) writes:
>In article <67563@tut.cis.ohio-state.edu> rosenbl@cis.ohio-state.edu (Robert Rosenblum) writes:
>>My routine
>>performs a linear search through the color map, comparing the
>>"distance" between my rgb value and each color map entry, and the
>>index of the closest color is returned.  However, this technique is
>>very slow.
>
>Are you doing a square root for each iteration?  If you are, that's
>one of your problems.  All you need is the relative "distance" between 
>the colors, and the squares of the distances will have the same relative
>ordering.
>
>Erich Stehr	"The Sorceress' Apprentice"	uunet!microsoft!erichs

The real problem here is searching (I assume) 256 entries for each pixel.
Paul Heckbert used a local search technique in his paper on color
reduction to reduce the list size:

"Color Image Quantization for Frame Buffer Display"
Paul Heckbert
ACM Transactions on Computer Graphics
Vol 16, Number 3 (July 1982)
pp. 297 - 304

Using this technique he was able to reduce the average number of tests 
from 256 to 11 for his test suite of 17 images.  Definitely worth looking
into.

If anyone knows of other methods that are faster or use less memory, please
post!

Sincerely,
   Ken Sykes

garnett@rpp386.cactus.org (John Garnett) (10/21/89)

In article <67563@tut.cis.ohio-state.edu> rosenbl@cis.ohio-state.edu 
(Robert Rosenblum) writes:
>I'm writing an application which involves taking a given rgb value and
>finding the color in the color map which is closest.  My routine
>performs a linear search through the color map, comparing the
>"distance" between my rgb value and each color map entry, and the
>index of the closest color is returned.  However, this technique is
>very slow.
>
>Is there is a more efficient way to find the closest color in a color
>map?  Any help would be greatly appreciated.

You may wish to investigate "An Algorithm for Finding Best Matches
in Logarithmic Expected Time" by Jerome M. Friedman, Jon Louis
Bentley, and Raphael Ari Finkel in the September 1977 issue of
the _ACM Transactions on Mathematical Software_, p. 209.

-- 
+------------------------------------+-----------------------------------+
| John Garnett                       |      Base 1.9                     |
| garnett@rpp386.cactus.org          |                                   |
| {bigtex|texbell}!rpp386!garnett    |      "It's almost binary"         |

planting@hobbes.cs.pittsburgh.edu (Dr. Harry Plantinga) (10/23/89)

In article <8134@microsoft.UUCP> kensy@microsoft.UUCP (Ken Sykes) writes:

>The real problem here is searching (I assume) 256 entries for each pixel.
>Paul Heckbert used a local search technique in his paper on color
>reduction to reduce the list size...
>
>If anyone knows of other methods that are faster or use less memory, please
>post!

I don't know if this is Paul Heckbert's technique, but in the
Macintosh toolbox Apple uses the following technique:

They construct an inverse color table based on the first 3-, 4-, or 5-
bits each of R, G, and B.  Thus, in order to find the best match for a
given color, you concatenate the first few bits of the R, G, and B
components and look up the best match in the inverse table.  If there
is more than one possibility, they are all stored and searched
sequentially.  This technique uses a table with 512, 4096, or 32768
entries.