I have a bunch of sports team logos. What I want to do is find the color that is used for the highest percentage of pixels. So, for the patriots logo below, I would pick out the blue or #000f47 (white will not be an acceptable color), as this is used for the highest percentage of pixels. Obviously I can eyeball each image, use the color picker tool in Gimp/Photoshop, and determine the color. However, I would like to script this if possible.
I can use any format for the picture input. Would it be possible to read the raw bitmap file format and determine this way? What would be an easy format to read? Do any tools support this, like ImageMagick, etc?
Thanks
If you're up for it then it's fairly straight forward to write your own image processor in C#; just run through the pixels, grab the R, G and, B values and increment a counter for each unique combination.
Having said that, if the image is anti-aliased then what you or I would eye-ball as being blue will be variations of the RGB and the processor would count them seperately. You might want to build in some allowable tollerances into the processor.
Just to be picky, isn't the most frequent pixel value in the image above white not blue?
Related
I'm new to GhostScript. Can you let me know the Ghostscript command for finding the number of colors used for each page in pdf file. I need to parse the results of this command from java program
There is no such Ghostscript command or device. It would also be difficult to figure out; so much depends on what you mean. Do you intend to count the colour of each pixel in every image for example ? Which colour spaces are you interested in ? What about ICCBased colour spaces, do you want the component values, or the CIE values ?
[edit]
Yeah there's no Ghostscript equivalent, I did say that.
You wuold have to intercept every call to the colour operators, examine the components being supplied and see if they were no black and white. For example, if you set a CMYK colour with C=M=Y=0 and K!=0 then its still black and white. Similar arguments apply for RGB, CIE and ICC colour spaces.
Now I bet ImageMagick doesn't do that, I suspect it simply uses Ghostscript to render a bitmap (probably RGB) and then counts the number of pixels of each colour in the output. Image manipulation tools pretty much all have to have a way to do that counting already, so its a low cost for them.
Its also wrong.
It doesn't tell you anything about the original colour. If you render a colour object to a colour space that is different to the one it was specified in, then the rendering engine has to convert it from the colour space it was in, to the expected one. This often leads to colour shifts, especially when converting from RGB to CMYK but any conversion will potentially have this problem.
So if this is what ImageMagick is doing, its inaccurate at best. It is possible to write PostScript to do this accurately, with some effort, but exactly what counts as 'colour' and 'black and white' is still a problem. You haven't said why you want to know if an input file is 'black and white' (you also haven't said if gray counts as black and white, its not the same thing)
I'm guessing you intend to either charge more for colour printing, or need to divert colour input to a different printer. In which case you do need to know if the PDF uses (eg) R=G=B=1 for black, because that often will not result in C=M=Y=0 K=1 when rendered to the printer. Not only that, but the exact colour produced may not even be the same from one printer to another (colour conversion is device-dependent), so just because Ghostscript produced pure black doesn't mean that another printer would.
This is not a simple subject.
I have a .png image that has been created from some grayscale numbers using Matlab's imagesc tool using the standard color map.
For some reason, I am unable to recover the raw data. Is there a way of recovering the raw data from the image? I tried rgb2gray which more or less worked, but if I replug the new image into imagesc, it gives me a slightly different result. Also, the pixel with the most intensity differs in both images.
So, to clarify: I would love to know, how Matlab applies the rgb colormap to the grayscale values, when using the standard colormap.
This is the image we are talking about:
http://imgur.com/qFsGrWw.png
Thank you!
No, you will not get the right data if you are using the standard colormap, or jet.
Generally, its a very bad thing to try to reverse engineer plots, as they will never contain the entirety of the information. This is true in general, but even more if you use colormaps that are do not change accordingly with the data. The amount of blue in jet is massively bigger in range than the amount of orange, or another color. The color changes are non-linear with the data changes, and this will make you miss a lot of resolution. You may know what value orange corresponds to, but blue will be a very wide range of possible values.
In short:
Triying to get data from representation of data (i.e. plots) is a terrible idea
jet is a terrible idea
I'm trying to develop a mobile application, and I'm wondering the easiest way to convert an image into a text file, and then be able to recreate it later in memory said text. The image(s) in question will contain no more than 16 or so colors, so it would work out fine.
Basically, brute-forcing this solution would require me saving each individual's pixel color data into a file. However, this would result in a HUGE file. I know there's a better way - like, if there's a huge portion of the image that consists of the same color, breaking up the area into smaller squares and rectangles and saving their coordinates and size to file.
Here's an example. The image is supposed to be just black/white. The big color boxes represent theoretical 'data points' in the outputted text file. These boxes would really state their origin, size, and what color they should be.
E.g., top box has an origin of 0,0, a size of 359,48, and it represents the color black.
Saved in a text file, the data would be 0,0,359,48,0.
What kind of algorithm would this be?
NOTE: The SDK that I am using cannot return a pixel's color from an X,Y coordinate. However, I can load external information into the program from a text file and manipulate it that way. This data that I need to export to a text file will be from a different utility that will have the capability to get a pixel's color from X,Y coordinates.
EDIT: Added a picture
EDIT2: Added constraints
Could you elaborate on why you want to save an image (or its parts) as plain text? Can't you use a binary representation instead? Also, if images typically have lots of contiguous runs of pixels of same color, you may want to use the so-called run-length encoding (RLE). Alternatively, one of Lempel-Ziv-something compression algorithms could be used (LZ77, LZ78, LZW).
Compress the image into a compressed format (e.g. JPEG, PNG, GIF, etc) and then save it as a .txt file or whatever. To recreate the image, just read in the file into your program using whatever library function suits your particular needs.
If it's necessary that the .txt file have some textual meaning, then you may be in some trouble.
In cs there is an algorithm like spatial index to recursivley subdivide a plane into 4 tiles. If the cell has the same size it looks like a quadtree. If want you to subdivide a plane into pattern (of colors) you can use this tiling idea to dynamically change the size of the cell. A good start to look at is a z-curve or a hilbert curve.
i'm working in a project to recognize a bit code from an image like this, where black rectangle represents 0 bit, and white (white space, not visible) 1 bit.
Somebody have any idea to process the image in order to extract this informations? My project is written in java, but any solution is accepted.
thanks all for support.
I'm not an expert in image processing, I try to apply Edge Detection using Canny Edge Detector Implementation, free java implementation find here. I used this complete image [http://img257.imageshack.us/img257/5323/colorimg.png], reduce it (scale factor = 0.4) to have fast processing and this is the result [http://img222.imageshack.us/img222/8255/colorimgout.png]. Now, how i can decode white rectangle with 0 bit value, and no rectangle with 1?
The image have 10 line X 16 columns. I don't use python, but i can try to convert it to Java.
Many thanks to support.
This is recognising good old OMR (optical mark recognition).
The solution varies depending on the quality and consistency of the data you get, so noise is important.
Using an image processing library will clearly help.
Simple case: No skew in the image and no stretch or shrinkage
Create a horizontal and vertical profile of the image. i.e. sum up values in all columns and all rows and store in arrays. for an image of MxN (width x height) you will have M cells in horizontal profile and N cells in vertical profile.
Use a thresholding to find out which cells are white (empty) and which are black. This assumes you will get at least a couple of entries in each row or column. So black cells will define a location of interest (where you will expect the marks).
Based on this, you can define in lozenges in the form and you get coordinates of lozenges (rectangles where you have marks) and then you just add up pixel values in each lozenge and based on the number, you can define if it has mark or not.
Case 2: Skew (slant in the image)
Use fourier (FFT) to find the slant value and then transform it.
Case 3: Stretch or shrink
Pretty much the same as 1 but noise is higher and reliability less.
Aliostad has made some good comments.
This is OMR and you will find it much easier to get good consistent results with a good image processing library. www.leptonica.com is a free open source 'C' library that would be a very good place to start. It could process the skew and thresholding tasks for you. Thresholding to B/W would be a good start.
Another option would be IEvolution - http://www.hi-components.com/nievolution.asp for .NET.
To be successful you will need some type of reference / registration marks to allow for skew and stretch especially if you are using document scanning or capturing from a camera image.
I am not familiar with Java, but in Python, you can use the imaging library to open the image. Then load the height and the widths, and segment the image into a grid accordingly, by Height/Rows and Width/Cols. Then, just look for black pixels in those regions, or whatever color PIL registers that black to be. This obviously relies on the grid like nature of the data.
Edit:
Doing Edge Detection may also be Fruitful. First apply an edge detection method like something from wikipedia. I have used the one found at archive.alwaysmovefast.com/basic-edge-detection-in-python.html. Then convert any grayscale value less than 180 (if you want the boxes darker just increase this value) into black and otherwise make it completely white. Then create bounding boxes, lines where the pixels are all white. If data isn't terribly skewed, then this should work pretty well, otherwise you may need to do more work. See here for the results: http://imm.io/2BLd
Edit2:
Denis, how large is your dataset and how large are the images? If you have thousands of these images, then it is not feasible to manually remove the borders (the red background and yellow bars). I think this is important to know before proceeding. Also, I think the prewitt edge detection may prove more useful in this case, since there appears to be less noise:
The previous method of segmenting may be applied, if you do preprocess to bin in the following manner, in which case you need only count the number of black or white pixels and threshold after some training samples.
i want to know the method of the images search according to the main object color in the images or the most used color in the image.
is there any tutorial, or even a product to buy it?
I would like to programming a search engine works with this feature.
so, can anybody help me
thank you.
I have done similar work. My implementation can be found here http://code.google.com/p/hppg/ . Live example can be found at project home page. This search engine also features search by keyword and colors at the same time. All detailed information and code can be found at project home page. Hope so it helps :)
Every color has an RGB value, indicating the levels of Red, Green and Blue in the color. You could calculate the sum of all RGB values for each pixel and then divide by the number of pixels, to get the "average" color of an image.
Another way to do it is flatten the colors (change all last digits in the RGB values to 0, for instance #F8824A becomes #F08040) and then find the largest surface in the image with the same color.
Imagine a photo of someone in front of a white wall - by using the first method you would get a mix of white and the person's clothes and face. Using the second method you would get white, unless the "color-constant" area of the person's shirt is bigger than the visible part of the wall.
There must be other ideas, but this should get you thinking about what you want.
Another option is to convert the image to HSV space (Hue, Saturation, Value), and calculate the mean hue. If the mean hue falls within a particular range, then keep the image, otherwise discard it. The particular range depends on the color you're interested in. For example, for green-ish images, you'd want anything with a hue between 60 and 180 degrees. See the HSV diagram below:
The benefit of working in HSV as opposed to RGB is that HSV is more naturally connected to how humans perceive color. RGB is more suited for displaying information in an additive color system, i.e. a computer monitor.
Depending on how much time you're willing to spend on this, you may not necessarily have to implement your own search engine. Just feed your query to Google's Image Search, crawl all the images from the result, and filter them using the above method (or some other criteria, like deltreme suggested above). I recently did something similar to grab maritime coastguard videos from Youtube (luckily, the ones I wanted were predominantly blue).
For the search part, check out Google's APIs. I haven't used one for image searching, but their Youtube API was very helpful.