Image classification using SIFT and SVM with Java - java

I have some images of flowers that I have extracted SIFT features from and I clustered the features using K-Means(k=3). I would like to create a "histogram of cluster membership identifiers" to feed to an SVM classifier as described in the accepted answer to the question below.
Large Scale Image Classifier
My question is, how do I create this histogram in Java? I'm using OpenCV, is there a method I have missed?
I have a Mat of centres where each row is a cluster centre and I have a Mat of labels where each element in a column is a cluster index (0...2) for each key point in an image.

Related

Changing a map image into nodes and edges

I'm developing an application and I have a map like the following and I want to extract the nodes and edges connecting these nodes in order to be able to apply any shortest path algorithm and have the data as a graph.
I used canny edge detector and it worked however it only displays the image after modification but doesn't save the data and I wanted it as vectors
What can I use to do do the following ???
Thanks in advanceenter image description here

How can i calculate a linear system using Matrix on Android?

I'm trying to solve a linear system on Android platform to perform some image processing. (OpenGL or Java Matrix).
Currently i have a 4x4 matrix and 4x1 vector represented as Matrix4f and Float4f respectively.
I want to divide them and save the output vector.
I need to use a Matrix because later i'll draw on the device screen a picture transformed by a matrix i'll generate from that vector result.
I could't find how to multiply the two on Android.
Already saw answers suggesting using a third party library ( JScience library ), but i prefer not to do so, only as a last resort.
Thanks.

Extract similar area of two images

I wonder that extracting similar area of images is possible. if it is possible,i am going to find insigne of copmany which created it.
There are two images below. The red rectangles in the images are that i try to find area. The program is going to find similar area comparing images. I tried to find it using opencv,but i couldn't do it.
First thing in mind:
Convert images to grayscale
Divide image into small areas (patches)
Each patch should be labelled as 1 if entropy of image is high and 0 if low (to discard patches without letters)
For two images, compare all patches across images based on:
Histogram on sobel image (Bhattacharya distance is normalized)
Correlation (Minmax normalization)
Advanced descriptors (like SIFT) (L2 normalization)
Min distance wins.
You can narrow down the '1' patches with a text detector (Algorithm to detect presence of text on image).

java image white color extraction

how to extract each image with white color into separate sections as shown below?
from the picture above, there will be nine separate section after the extract
I have tried several algorithms such as fillgrid but not exactly what I expected.
so that I could store every sections into a PostGIS database as polygon geometry
What algorithm can I use?
or maybe there is a function in java or postgis library?
This thread may help you but I think you could do this by finding the differences in colour in your image.
You need to "polygonise" your raster data into vectors.
One such tool is from GDAL, with a method originally in C++, but also has bindings to Java.
Java bindings (search for "Polygonize")
C API description of parameters for GDALPolygonize
Some further hints on using the Polygonize method is that you will need to classify values of your raster as "NO DATA" values, then polygonise the remaining data portion. The resulting polygon can be placed in most geospatial vector formats, including a PostGIS database.
Another solution is to load the image into PostGIS raster, then use either ST_Polygon or ST_DumpAsPolygons to do essentially the same task as GDALPolygonize, but with fewer options.

How to detect if an image is a photo, clip art or a line drawing?

What is the best way to identify an image's type? rwong's answer on this question suggests that Google segments images into the following groups:
Photo - continuous-tone
Clip art - smooth shading
Line drawing - bitonal
What is the best strategy for classifying an image into one of those groups? I'm currently using Java but any general approaches are welcome.
Thanks!
Update:
I tried the unique colour counting method that tyjkenn mentioned in a comment and it seems to work for about 90% of the cases that I've tried. In particular black and white photos are hard to correctly detect using unique colour count alone.
Getting the image histogram and counting the peeks alone doesn't seem like it will be a viable option. For example this image only has two peaks:
Here are two more images I've checked out:
Rather simple, but effective approaches to differentiate between drawings and photos. Use them in combination to achieve a the best accuracy:
1) Mime type or file extension
PNGs are typically clip arts or drawings, while JPEGs are mostly photos.
2) Transparency
If the image has an alpha channel, it's most likely a drawing. In case an alpha channel exists, you can additionally iterate over all pixels to check if transparency is indeed used. Here a Python example code:
from PIL import Image
img = Image.open('test.png')
transparency = False
if img.mode in ('RGBA', 'RGBa', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
if img.mode != 'RGBA': img = img.convert('RGBA')
transparency = any(px for px in img.getdata() if px[3] < 220)
print 'Transparency:', transparency
3) Color distribution
Clip arts often have regions with identical colors. If a few color make up a significant part of the image, it's rather a drawing than a photo. This code outputs the percentage of the image area that is made from the ten most used colors (Python example):
from PIL import Image
img = Image.open('test.jpg')
img.thumbnail((200, 200), Image.ANTIALIAS)
w, h = img.size
print sum(x[0] for x in sorted(img.convert('RGB').getcolors(w*h), key=lambda x: x[0], reverse=True)[:10])/float((w*h))
You need to adapt and optimize those values. Is ten colors enough for your data? What percentage is working best for you. Find it out by testing a larger number of sample images. 30% or more is typically a clip art. Not for sky photos or the likes, though. Therefore, we need another method - the next one.
4) Sharp edge detection via FFT
Sharp edges result in high frequencies in a Fourier spectrum. And typically such features are more often found in drawings (another Python snippet):
from PIL import Image
import numpy as np
img = Image.open('test.jpg').convert('L')
values = abs(numpy.fft.fft2(numpy.asarray(img.convert('L')))).flatten().tolist()
high_values = [x for x in values if x > 10000]
high_values_ratio = 100*(float(len(high_values))/len(values))
print high_values_ratio
This code gives you the number of frequencies that are above one million per area. Again: optimize such numbers according to your sample images.
Combine and optimize these methods for your image set. Let me know if you can improve this - or just edit this answer, please. I'd like to improve it myself :-)
This problem can be solved by image classification and that's probably Google's solution to the problem. Basically, what you have to do is (i) get a set of images labeled into 3 categories: photo, clip-art and line drawing; (ii) extract features from these images; (iii) use the image's features and label to train a classifier.
Feature Extraction:
In this step you have to extract visual information that may be useful for the classifier to discriminate between the 3 categories of images:
A very basic yet useful visual feature is the image histogram and its variants. For example, the gray level histogram of a photo is probably smoother than a histogram of a clipart, where you have regions that may be all of the same color value.
Another feature that one can use is to convert the image to the frequency domain (e.g. using FFT or DCT) and measure the energy of high frequency components. Because line drawings will probably have sharp transitions of colors, its high frequency components will tend to accumulate more energy.
There's also a number of other feature extraction algorithms that may be used.
Training a Classifier:
After the feature extraction phase, we will have for each image a vector of numeric values (let's call it the image feature vector) and its tuple. That's a suitable input for a training a classifier. As for the classifier, one may consider Neural Networks, SVM and others.
Classification:
Now that we have a trained classifier, to classify an image (i.e. detect a image category) we simply have to extract its features and input it to the classifier and it will return its predicted category
Histograms would be a first way to do this.
Convert the color image to grayscale and calculate the histogram.
A very bi-modal histogram with 2 sharp peaks in black (or dark) and white (or right), probably with much more white, are a good indication for line-drawing.
If you have just a few more peaks then it is likely a clip-art type image.
Otherwise it's a photo.
In addition to color histograms, also consider edge information and the consistency of line widths throughout the image.
Photo - natural edges will have a variety of edge strengths, and it's less likely that there will be many parallel edges.
Clip art - A watershed algorithm could help identify large, connected regions of consistent brightness. In clip art and synthetic images designed for high visibility there are more likely to be perfectly straight lines and parallel lines. A histogram of edge strengths is likely to have a few very strong peaks.
Line drawing - synthetic lines are likely to have very consistent width. The Stroke Width Transform could help you identify strokes. (One of the basic principles is to find edge gradients that "point at" each other.) A histogram of edge strengths may have only one strong peak.

Categories

Resources