|
-
Feb 26th, 2004, 05:15 AM
#1
Thread Starter
New Member
Convertin colors to more simple colors in an image.
Hi all,
I am developing a project and I need your advices.
We are manufacturing marble. Some people take photographs of marbles with digital camera and send it to us.
Until now, we open all images and write which kind of marble.
Every marble has its own characteristic.
For example one's characteristic is
white background and black vessels on it
the other's
orange background and grey vessels on it.
Now I trying to recognize marble kind with visual basic.
This will my future steps,
1.(which I don't know how to do it) Convert all colors to an most approximate simple color. For example
Lightskyblue= blue
Lightsteelblue= blue
.
.
.
Lightyellow = yellow
Wheat= yellow
.
.
.
How can I do it with rgb or hex values. (Or it is possible to use color palettes?)
2. (I can do it) Count every color in new image. Then sort them in most repetition in descending order. Then pick 2 or 3 top colors to define which kind of marble.
Could you please help, or have different advices?
Thank in advance.
Last edited by googleelgoog; Feb 26th, 2004 at 05:54 AM.
-
Feb 26th, 2004, 07:57 AM
#2
I am not good with palettes, so I can't help you there...maybe someone else can.
But the other way you could use the GetPixel API to get the color from the picture in a picturebox or something. If you do that all over the image you can check what color it is. You have to make a function that defines what is
Lightskyblue= blue
Lightsteelblue= blue
and so on. If you look how much Red and Green and Blue color there is from the result, you should make a conclusion if it is Blue, and what kind of blue it is.
The biggest problem here is if they take a picture and get more then the floor on the picture. Then your function will add that too. But not sure if that is a problem for you.....
-
Feb 26th, 2004, 08:08 PM
#3
transcendental analytic
It depends on your choice of "simple" palette. There are different ways of calculating distance between colours but depending on the method you can arrive at the closest colour. Easiest would be to use the ones used on your display: black, white, red, green, blue, yellow, magenta and cyan
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Feb 26th, 2004, 11:19 PM
#4
Frenzied Member
try doing something like this:
loop through all pixels and then check the rgb values
if red > 150 and green < 100 and blue < 100 then
'this color is probably red
etc...
you should change those values so that it gives the best result and add alot of more ifs.
-
Apr 16th, 2004, 10:45 AM
#5
Fanatic Member
I have been looking to do the same thing.
After looking round the internet for days and including lots of forums I have come to the same conclusion as cyborg. looping through each pixel.
However I don't like the idea of comparing the Red, Green and Blue value individually of every pixel.
Is it possible to convert the RGB value into something for easier comparison, say a single long value. You can then create a lookup table with the upper and lower bounds for red.
Does anyone know of a way to convert the RGB value into a single value?
-
Apr 16th, 2004, 12:30 PM
#6
Can't you do something like
VB Code:
Dim lColor as Long
lColor = RGB(lRed, lGreen, lBlue)
-
Apr 16th, 2004, 12:33 PM
#7
I even looked it up for you...
Returns aLong whole number representing an RGB color value.
Syntax
RGB(red, green, blue)
The RGB function syntax has thesenamed arguments:
Part Description
red Required; Variant (Integer). Number in the range 0–255, inclusive, that represents the red component of the color.
green Required; Variant (Integer). Number in the range 0–255, inclusive, that represents the green component of the color.
blue Required; Variant (Integer). Number in the range 0–255, inclusive, that represents the blue component of the color.
Remarks
Applicationmethods andproperties that accept a color specification expect that specification to be a number representing an RGB color value. An RGB color value specifies the relative intensity of red, green, and blue to cause a specific color to be displayed.
The value for anyargument to RGB that exceeds 255 is assumed to be 255.
The following table lists some standard colors and the red, green, and blue values they include:
Color Red Value Green Value Blue Value
Black 0 0 0
Blue 0 0 255
Green 0 255 0
Cyan 0 255 255
Red 255 0 0
Magenta 255 0 255
Yellow 255 255 0
White 255 255 255
-
Apr 16th, 2004, 01:42 PM
#8
Fanatic Member
What more could I ask.
Thats brilliant.
-
Apr 16th, 2004, 09:24 PM
#9
Ex-Super Mod'rater
Once a RGB color has been put in a Long theres not much you can do to compare it. For example if the Red part is increased by 1 the chnage is way different to just adding one onto the Blue. This is because the Bits are stored like:
RRRR RRRR GGGG GGGG BBBB BBBB
It could be an idea to just add up the values of all the Reds for every pixel, same for greens & blues then take an average of them all. This would require a rather large number though if the image is big so I dont know if a Long would be big enough to hold all the values of a color from a image.
You might find it useful for your program to blur the image before it does anything with it as well. I find this useful because if your looking for trends it will be too picky about it not being exact if you dont blur it. Bluring wont effect finding the average color though (Unless you look for the most popular color then it will).
Theres my two cents .
When your thread has been resolved please edit the original post in the thread (  )
and amend "-[RESOLVED]-" to the end of the title and change the icon to  , Thank you.
When posting Code use the [VBCode]Code Here[/VBCode] tags to be able to use the code highlighting.

-
Apr 17th, 2004, 02:28 PM
#10
So Unbanned
There are palette APIs which would allow you to scan an image, return unique palette entries(then based on your pre-defined RGB entries in the palette replace it with a color matching it.)
Another way would be to convert RGB into HSL(sometimes called HSV... hue(color),sat.(how 'rich' the color is)lum.(brightness)).
Then you'd take the values, select case them using ranges, and come out with a fairly good description of the marble(atleast color-wise). The hard part would be describing things such as the 'eye' or vessels.
-
Apr 17th, 2004, 02:43 PM
#11
Fanatic Member
Originally posted by DiGiTaIErRoR
There are palette APIs which would allow you to scan an image, return unique palette entries(then based on your pre-defined RGB entries in the palette replace it with a color matching it.)
Another way would be to convert RGB into HSL(sometimes called HSV... hue(color),sat.(how 'rich' the color is)lum.(brightness)).
Then you'd take the values, select case them using ranges, and come out with a fairly good description of the marble(atleast color-wise). The hard part would be describing things such as the 'eye' or vessels.
Do you know of any examples of these methods.
-
Apr 17th, 2004, 03:03 PM
#12
So Unbanned
Public Type PALETTEENTRY
peRed As Byte
peGreen As Byte
peBlue As Byte
peFlags As Byte
End Type
Public Type LOGPALETTE
palVersion As Integer
palNumEntries As Integer
palPalEntry(255) As PALETTEENTRY
End Type
'types for palette creation
Private Declare Function CreatePalette Lib "gdi32" (lpLogPalette As LOGPALETTE) As Long
Is used to create a logical palette.
Public Declare Function GetNearestPaletteIndex Lib "gdi32" (ByVal hPalette As Long, ByVal crColor As Long) As Long
Will return the palette index of the nearest color to crColor in hPalette.
You'll then have to declare some memory types...
Public Pal As LOGPALETTE
Public hPal As Long 'handle to the palette(will be set = createpalette)
Now the code...
VB Code:
Pal.palNumEntries = 256
Pal.palVersion = &H300 'defines our palette entries and type of palette
'define the colors in the palette
Pal.palpalEntry(x).peRed = 1
Pal.palpalEntry(x).peGreen = 2
Pal.palpalEntry(x).peBlue = 3
'When you've set the colors in the palette, you now do:
hPal = CreatePalette(Pal)
x = GetNearestPaletteIndex(hPal, somecolor)
'now to retieve the palette's 'approximate' of somecolor
r = Pal.palpalEntry(x).peRed
g = Pal.palpalEntry(x).peGreen
b = Pal.palpalEntry(x).peBlue
A simple Google search should provide a method to convert HSL(HSV)<->RGB. Or try PSC.
Last edited by DiGiTaIErRoR; Apr 18th, 2004 at 05:54 AM.
-
Apr 17th, 2004, 04:51 PM
#13
Fanatic Member
DiGiTaIErRoR, Looking at your code there are a few things I am unsure of.[list=1][*]Where does modprop come from?
hPal = CreatePalette(modProp.Pal)
[*]I noticed you declared 255 palette entries but only initialised the RGB of one entry. Can I have any number of entries, 10,100 or 201.[/list=1]
I looked on www.allapi.net for additional help but could not find GetNearestPaletteIndex.
-
Apr 18th, 2004, 05:55 AM
#14
So Unbanned
A module, lol.
Yup, you can pick any number(1-256).
palPalEntry(255) As PALETTEENTRY = 0 to 255 or 256 total
-
Apr 18th, 2004, 06:03 AM
#15
Originally posted by davidrobin
I looked on www.allapi.net for additional help but could not find GetNearestPaletteIndex.
From MSDN (not sure if it can help you)...
GetNearestPaletteIndex
The GetNearestPaletteIndex function retrieves the index for the entry in the specified logical palette most closely matching a specified color value.
UINT GetNearestPaletteIndex(
HPALETTE hpal, // handle of logical color palette
COLORREF crColor // color to be matched
);
Parameters
hpal
Handle to a logical color palette.
crColor
Specifies a color to be matched.
Return Values
If the function succeeds, the return value is the index of an entry in a logical palette.
If the function fails, the return value is CLR_INVALID.
Windows NT: To get extended error information, callGetLastError.
Remarks
An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.
If the given logical palette contains entries with the PC_EXPLICIT flag set, the return value is undefined.
QuickInfo
Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in wingdi.h.
Import Library: Use gdi32.lib.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|