Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image Classification - Detecting Floor Plans

I am working on a real estate website and i would like to write a program that can figure out(classify) if an image is a floor plan or a company logo.

Since i am writing in php i will prefer a php solution but any c++ or opencv solution will be fine as well.

Floor Plan Sample:

alt text http://www.rentingtime.com/uploads/listing/l0050/0000050930/68614.jpg

alt text http://www.rentingtime.com/uploads/listing/l0031/0000031701/44199.jpg

Logo Sample:

alt text http://www.rentingtime.com/uploads/listing/l0091/0000091285/95205.jpg

like image 874
user235410 Avatar asked Dec 08 '22 05:12

user235410


1 Answers

As always, there is a built-in PHP function for this. Just joking. =)

All the floor plans I've seen they are pretty monochromatic, I think you can play with the number of colors and color saturation to have a pretty good guess is the image is a logo or a floor plan.

E.g.: is the image has less than 2 or 3 colors is a floor plan.

E.g.: if the sum / average of the saturation is less than X it's a floor plan.

Black and white (and other similar colors that are used in floor plans) have a saturation that is zero, or very close to zero, while logos tend to be more visually attractive, hence use more saturated colors.

Here is a simple function to compute the saturation of a Hex RGB color:

function Saturation($color)
{
    $color = array_map('hexdec', str_split($color, 2));

    if (max($color) > 0)
    {
        return (max($color) - min($color)) / max($color);
    }

    return 0;
}

var_dump(Saturation('000000')); // black    0.0000000000000000
var_dump(Saturation('FFFFFF')); // white    0.0000000000000000
var_dump(Saturation('818185')); // grey     0.0300751879699249
var_dump(Saturation('5B9058')); // green    0.3888888888888889
var_dump(Saturation('DE1C5F')); // pink     0.8738738738738738
var_dump(Saturation('FE7A15')); // orange   0.9173228346456692
var_dump(Saturation('FF0000')); // red      1.0000000000000000
var_dump(Saturation('80FF80')); // ---      0.4980392156862745
var_dump(Saturation('000080')); // ---      1.0000000000000000

Using imagecolorat() and imagecolorsforindex() you can implement a simple function that loops trough all the pixels of the image and sums / computes the average of the saturation. If the image has a saturation level above of a custom threshold you define you can assume that the image is a logo.

One thing you shouldn't forget is that images that have a higher resolution will normally have more saturation (more pixels to sum), so for the sake of this algorithm and also for the sake of your server performance it would be wise to resize all the images to a common resolution (say 100x100 or 50x50) to classify them and once classified you could use the original (non-resized) images.

I made a simple test with the images you provided, here is the code I used:

$images = array('./44199.jpg', './68614.jpg', './95205.jpg', './logo.png', './logo.gif');

foreach ($images as $image)
{
    $sat = 0;
    $image = ImageCreateFromString(file_get_contents($image));

    for ($x = 0; $x < ImageSX($image); $x++)
    {
        for ($y = 0; $y < ImageSY($image); $y++)
        {
            $color = ImageColorsForIndex($image, ImageColorAt($image, $x, $y));

            if (is_array($color) === true)
            {
                $sat += Saturation(dechex($color['red']) . dechex($color['green']) . dechex($color['blue']));
            }
        }
    }

    echo ($sat / (ImageSX($image) * ImageSY($image)));
    echo '<hr />';
}

And here are the results:

green floor plant:      0.0151028053
black floor plant:      0.0000278867
black and white logo:   0.1245559912
stackoverflow logo:     0.0399864136
google logo:            0.1259357324

Using only these examples, I would say the image is a floor plant if the average saturation is less than 0.03 or 0.035, you can tweak it a little further by adding extra examples.

like image 189
Alix Axel Avatar answered Jan 03 '23 23:01

Alix Axel