图像分类 - 检测楼层平面图

时间:2009-12-20 08:31:07

标签: php image-processing opencv pattern-matching classification

我正在开发一个房地产网站,我想写一个程序 如果图像是平面图或公司徽标,可以弄清楚(分类)。

由于我在php中编写,我更喜欢php解决方案,但任何c ++或opencv解决方案都可以。

平面图样本:

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

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

徽标样本:

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

9 个答案:

答案 0 :(得分:6)

与往常一样,有一个built-in PHP function for this。只是在开玩笑。 =)

我看到的所有平面图都非常单色,我认为你可以使用颜色数量和颜色饱和度来猜测图像是徽标还是平面图。

例如:is the image has less than 2 or 3 colors is a floor plan.

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

黑色和白色(以及平面图中使用的其他类似颜色)的饱和度为零或非常接近零,而徽标往往更具视觉吸引力,因此使用更饱和的颜色。

这是一个计算Hex RGB颜色饱和度的简单函数:

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

使用imagecolorat()imagecolorsforindex(),您可以实现一个简单的函数,该函数循环遍历图像的所有像素,并求和/计算饱和度的平均值。如果图像的饱和度高于自定义阈值,则可以假定图像是徽标。

你不应该忘记的一件事是,具有更高分辨率的图像通常会有更多的饱和度(更多的像素要求和),所以为了这个算法而且为了你的服务器性能,这将是明智的将所有图像调整为通用分辨率(例如100x100或50x50)以对其进行分类,一旦分类,您可以使用原始(未调整大小)的图像。

我使用您提供的图片进行了简单的测试,这是我使用的代码:

$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 />';
}

以下是结果:

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

仅使用这些示例,如果平均饱和度小于0.03或0.035,我会说图像是地板工厂,您可以通过添加额外的示例进一步调整它。

答案 1 :(得分:3)

将此外包给人类可能最容易。

如果您有预算,请考虑Amazon's Mechanical Turk。请参阅Wikipedia以获取general description

或者,您可以自己进行外包。编写一个PHP脚本来显示您的一个图像,并提示用户将其排序为“logo”我们的“平面图”。一旦您在网络服务器上运行,请通过电子邮件发送给您的整个办公室,并要求每个人将20张图片分类为个人青睐。

更好的是,让它成为一场比赛 - 对图像进行分类的人将赢得一个ipod!

也许最简单的是,邀请你认识的每个人吃披萨和啤酒,并设置一堆笔记本电脑,让大家花几分钟时间进行分类。

有软件方法可以完成你的任务,但如果它是一次性事件,图像少于几千,预算至少几百美元,那么我认为你的生活可能更容易使用人类。

答案 2 :(得分:2)

首先想到的事情之一是,平面图往往有比90度更多的线条比任何正常的标志更多。

快速首过将是在图像上运行Canny edge detection并使用Hough transform和线的rho,Theta定义对角度进行投票。如果您看到Theta =(0,90,180,270)与rho相加的非常强的对应关系,则可以将图像分类为平面图。

另一种选择是在Canny步骤之后走边缘图像,仅计算来自长而连续线段的投票,消除噪音。

答案 3 :(得分:1)

我非常怀疑任何这样的工具已经存在,并且创建任何准确的工具都是非常重要的。如果您需要整理一组现有图像(例如,您有一个未排序的目录),那么您可以编写一个“足够好”的工具并手动处理故障。如果您需要使用新图像动态执行此操作,则可能是错误的方法。

如果我在前一种情况下尝试这种方法,我可能会寻找一些与我可以用作代理的完全不同的东西。楼层平面图通常比徽标(文件大小或图像尺寸)大很多?平面图的颜色是否比徽标少?如果我能用一些微不足道的东西获得75%的准确率,那么可能就是这样。

答案 4 :(得分:1)

像这样的东西 - 图像中图案的重新定义 - 在时间方面往往非常昂贵,非常不可靠,并且不断需要更新和修补以匹配新案例。

我可以问你为什么需要这样做?您网站的工作流程中是否没有一点可以手动确定图像是徽标还是平面图?编写一个允许用户确定上传时哪个应用程序的应用程序会不会更容易?为什么首先会有一组混合数据?

答案 5 :(得分:1)

尽管认为这需要人工干预,但您可以做的一件事就是检查图像的大小。

小(在MB和尺寸方面)图像可能是徽标。

大(在MB和尺寸方面)图像可能是平面图。

但是,这只是一种概率测量,绝不是万无一失的。

图像类型也是一个指标,但不是一个。徽标更可能是JPG,PNG或GIF,平面图可能是TIFF或其他无损格式 - 但这不是保证。

答案 6 :(得分:1)

我首先尝试的一个简单明智的尝试是使用SVM来学习从样本中获得的SIFT关键点。但在你能做到这一点之前,你需要标记一小部分图像,给它-1(平面图)或1(徽标)。如果图像有更多的关键点被归类为平面图,那么它必须是平面图,如果它有更多的关键点被归类为徽标,那么它必须是徽标。在计算机视觉中,这被称为特征包方法,也是最简单的方法之一。更复杂的方法可能会产生更好的结果,但这是一个良好的开端。

答案 7 :(得分:0)

正如其他人所说,这种图像识别通常非常复杂。忘了PHP。

但是,查看您的示例时,我会看到 MIGHT 的标准非常好,并且如果有的话很容易实现:

通过良好的OCR运行图像,查看弹出的字符串。如果你找到一堆描述房间或这些特征的词......

我将图像旋转90度并再次尝试捕捉垂直标签。

编辑: 既然你说你尝试了它并且它不起作用,你可能需要先清除杂乱。根据空白切片图像。对每个子图像运行OCR,以防它变得混乱,试图解析这些线。您可以使用图像编辑器手动对其进行测试以对其进行切片。

答案 8 :(得分:0)

同时使用颜色饱和度图像尺寸(两者均在之前的答案中单独提出)。使用大量人类分类数字样本,看看它们如何在二维空间(大小x饱和度)中绘制,然后决定放置边界的位置。边界不需要是一条直线,但是不要做太多的扭曲试图使所有点都适合,否则你将以新数据为代价“记忆”样本。最好找到一个适合大多数样本的相对简单的边界,它应该适合大多数数据。

你必须容忍某个错误。一个万无一失的解决方案是不可能的。如果我选择平面图作为我公司的徽标怎么办? (这不是一个玩笑,它恰好很有趣)