4

私は不動産のウェブサイトに取り組んでおり、画像がフロア プランであるか会社のロゴであるかを把握 (分類) できるプログラムを書きたいと考えています。

私はphpで書いているので、phpソリューションを好みますが、c ++またはopencvソリューションも問題ありません。

フロアプランのサンプル:

代替テキスト http://www.rentingtime.com/uploads/listing/l0050/0000050930/68614.jpg

代替テキスト http://www.rentingtime.com/uploads/listing/l0031/0000031701/44199.jpg

ロゴのサンプル:

代替テキスト http://www.rentingtime.com/uploads/listing/l0091/0000091285/95205.jpg

4

9 に答える 9

6

いつものように、このための組み込みのPHP関数があります。ほんの冗談ですよ。=)

私が見たすべての間取り図はかなり単色です。画像がロゴまたは間取り図であるかどうかをかなり推測するために、色の数と彩度を試してみることができると思います。

例えば: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.

黒と白(およびフロアプランで使用される他の同様の色)の彩度はゼロまたはゼロに非常に近いですが、ロゴは視覚的に魅力的である傾向があるため、より彩度の高い色を使用します。

16進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()を使用すると、画像のすべてのピクセルをループして飽和の平均を合計/計算する単純な関数を実装できます。画像の飽和レベルが定義したカスタムしきい値を超えている場合は、画像がロゴであると見なすことができます。

忘れてはならないことの1つは、解像度が高い画像ほど飽和度が高くなる(合計するピクセル数が増える)ことです。したがって、このアルゴリズムとサーバーパフォーマンスのために、すべてのサイズを変更することをお勧めします。画像を一般的な解像度(たとえば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未満の場合、画像は床の植物であると言えます。例を追加することで、画像をもう少し微調整できます。

于 2009-12-20T17:08:42.620 に答える
3

これを人間に外注するのが最も簡単かもしれません。

予算があれば AmazonのMechanical Turkを検討してみてください。一般的な説明については、ウィキペディアを参照してください。

または、アウトソーシングを自分で行うこともできます。画像の 1 つを表示する PHP スクリプトを作成し、ユーザーにそれを「ロゴ」または「間取り図」のいずれかに分類するように促します。これを Web サーバーで実行したら、オフィス全体にメールを送信し、個人的な好みとして 20 枚の画像を並べ替えるよう全員に依頼します。

いっそのこと、コンテストにしましょう。最も多くの画像を並べ替えた人が iPod を獲得します。

おそらく最も簡単なのは、知り合い全員をピザとビールに招待し、たくさんのラップトップをセットアップして、全員に数分間仕分けをしてもらうことです。

タスクを達成するためのソフトウェアの方法はありますが、画像数が数千未満で、予算が少なくとも数百ドルの 1 回限りのイベントである場合は、人間を使用する方が簡単であると思います。

于 2010-01-11T04:42:05.493 に答える
2

最初に頭に浮かぶことの 1 つは、フロア プランには、通常のロゴよりも 90 度を向いた線がかなり多い傾向があるという事実です。

高速な最初のパスは、画像に対してキャニー エッジ検出を実行し、ハフ変換と rho (線のシータ定義) を使用して角度に投票することです。ローを合計した Theta=(0, 90, 180, 270) の非常に強い対応が見られる場合は、その画像を間取り図として分類できます。

もう 1 つのオプションは、キャニー ステップの後にエッジ イメージをウォークして、長く連続したライン セグメントからの票のみをカウントし、ノイズを除去することです。

于 2009-12-21T19:29:34.907 に答える
1

このようなもの(画像のパターンの認識)は、時間の点で恐ろしく高価であり、恐ろしく信頼性が低く、新しいケースに一致するように更新とパッチを適用する必要があります。

なぜこれをする必要があるのか​​聞いてもいいですか?Webサイトのワークフローに、画像がロゴであるか間取り図であるかを手動で判断できるポイントはありませんか?アップロード時にどちらがどちらかをユーザーが判断できるアプリケーションを作成する方が簡単ではないでしょうか。そもそもなぜ混合データセットがあるのですか?

于 2009-12-20T17:18:59.647 に答える
0

色の彩度画像サイズの両方を使用します(両方とも以前の回答で個別に提案されています)。人間に分類された人物の大きなサンプルを使用して、それらが 2 次元空間 (サイズ x 彩度) でどのようにプロットされるかを確認してから、境界を置く場所を決定します。境界線は直線である必要はありませんが、すべての点が収まるようにねじれすぎないようにしてください。そうしないと、新しいデータを犠牲にしてサンプルを「メモリ化」することになります。ほとんどのサンプルに適合する比較的単純な境界を見つける方が適切であり、ほとんどのデータに適合するはずです。

特定のエラーを許容する必要があります。これに対する絶対確実な解決策は不可能です。会社のロゴとしてフロアプランを選択した場合はどうなりますか? (これは冗談ではなく、たまたま笑っただけです)

于 2009-12-21T19:30:51.733 に答える
0

他の人が言ったように、そのような画像認識は通常恐ろしく複雑です。PHPを忘れてください。

ただし、サンプルを見てみると、かなりうまく機能する可能性があり、実装が非常に簡単な基準がわかりました。

適切な OCR で画像を実行し、どの文字列が飛び出すかを確認します。部屋やそのような機能を説明する言葉がたくさんある場合...

画像を 90 度回転させて、もう一度垂直ラベルをキャッチしようとします。

編集:試してみてうまくいかなかったと言うので、最初に混乱を一掃する必要があるかもしれません。空白に基づいて画像をスライスします。行を解析しようとしてめちゃくちゃになった場合に備えて、各サブイメージに対して OCR を実行します。画像エディタを使用して手動でテストし、スライスすることができます。

于 2009-12-20T19:01:45.833 に答える