9

SO で以前に尋ねたこのような質問があります: Detecting a pixelated image in python and also on quora

ユーザーがアップロードした画像を「ピクセル化」として検出できるかどうかを調べようとしています。ピクセル化とは、次のような画像を意味します。私の場合、元の(ピクセル化されていない)バージョンにアクセスできません。

私のアプローチ

このアプローチがどれほど効果的かはわかりませんが、画像内の各ピクセルの RGB を取得し、それを隣接するピクセルと比較して類似しているかどうかを確認できれば、画像がピクセル化されていることを検出できますか? ピクセルの RGB を取得できますが、隣接するピクセルと比較する方法がわかりません。

このようなことを行うためのアルゴリズムは既に利用可能ですか? 私が取ることができる他のいくつかのアプローチはありますか?私は特定の言語に縛られていません。

4

3 に答える 3

10

これはうまくいく可能性のあるかなり単純なアプローチです:

  1. x と y の両方で 1 ピクセルだけ翻訳されたコピーから画像を減算します。
  2. 列と行のピクセルを合計します (以下に列のみを示します)。
  3. ピーク位置の周波数と標準偏差を計算します。
  4. 標準偏差があるしきい値を下回る場合、画像はピクセル化されます。

ステップ 1 後のイメージ:

ここに画像の説明を入力

明確なグリッド パターンを表示します。ピクセルを列ごとに合計すると、次のようになります。

ここに画像の説明を入力 ここで、ピークの列間隔の規則性を把握し、これをしきい値として使用して、画像がピクセル化されているかどうかを判断できれば.

アプローチのアイデアを提供するために、いくつかの簡単で大まかなPythonコードを次に示します。

import numpy as np
import Image, ImageChops

im = Image.open('fireworks-pixelate-02.gif')    
im2 = im.transform(im.size, Image.AFFINE, (1,0,1,0,1,1))
im3 = ImageChops.subtract(im, im2)
im3 = np.asarray(im3)
im3 = np.sum(im3,axis=0)[:-1]
mean = np.mean(im3)
peak_spacing = np.diff([i for i,v in enumerate(im3) if v > mean*2])
mean_spacing = np.mean(peak_spacing)
std_spacing = np.std(peak_spacing)
print 'mean gap:', mean_spacing, 'std', std_spacing

出力:

mean gap: 14.6944444444 std: 3.23882218342

低標準 = ピクセル化された画像

このピクセル化されていない画像: ここに画像の説明を入力

次のような対応するグラフがあります。

ここに画像の説明を入力 はるかに高いstdをもたらします:

mean gap: 16.1666666667 std: 26.8416136293

ここで、標準がはるかに高いため、「平均ギャップ」は無意味であることに注意してください。

願わくば、これで、このアプローチが非常にうまく機能することを示すのに十分です。

于 2013-01-19T23:36:10.897 に答える
7

いくつかのアプローチ:

1) キャニーまたはその他のエッジ検出を実装し、エッジしきい値を変更して、結果がグリッドであるかどうかを確認します。得られたエッジ画像にハフ線検出器を適用することにより、グリッドを検出できます。以下の(2)を参照してください。

2) (これは実際にはエッジ検出の前に画像をしきい値処理しています。メディアン フィルターまたは他のノイズ除去フィルターを使用して画像を平滑化することもお勧めします)。左から右にスキャンし、ピクセルの色が変化するたびに、黒または白のいずれかをピクセルに割り当てます。色が変わるまで黒/白を続け、黒から白、または白から黒に切り替えます。ピクセル化すると、グリッドのような画像になります。iamge で標準の線検出を実行し ( 1に対しても実行できます)、結果の線の傾きが垂直で平行であるかどうか、および線がかなり等距離であるかどうかを確認できます。インターネット上にはサンプル行検出アルゴリズムがあります (Java 実装も含まれます)。

このWeb サイトには、線検出アルゴリズムとエッジ検出アルゴリズムへの参照があります。

編集: mmgp からの質問に答えて (チャレンジの +1、私はそれが好きです!)、これは私が質問のサンプル画像で行ったことです: 1) エッジ検出 2) グレースケール 3) ヒュー変換 (高しきい値) ヒュー変換出力が添付されています。水平/垂直勾配を持つすべての線を評価し、それらの間の距離を計算することで、グリッド パターンを識別することができます。これは、画像がピクセル化されていることを自動的に意味するわけではありません (チェス盤はピクセル化されて表示されます)。誤検知が発生する可能性があります。

ここに画像の説明を入力

于 2013-01-19T21:25:35.643 に答える
2

これは問題になるでしょう。画像をピクセル化する方法はたくさんあります。単一の方法でも、任意に回転させることができます。理論的には、この回転は Hough のようなメソッドに影響を与えるべきではありませんが、実際には、任意の角度で完全にラスタライズされた線を作成することはできないため、影響を受けます。私のアプローチは単純化されており、毎回うまくいくわけではありません (ほとんどの場合失敗するでしょう)。ユーザーに「あなたの画像はピクセル化されています。私はそれを望んでいません」と言いますか? やりたいことが明確でない、範囲も明確でない。

だからここにアプローチがあります。画像をカラー チャネルに分割します。例の 1 つはパレット GIF ですが、RGB 画像として簡単に見ることができます。グレースケールの場合は、ほとんどの場合、1 つのチャネルが必要です。それで問題ありません。画像にアルファ チャネルがある場合は、ブレンドするか無視します。この分離されたカラー チャネルを使用して、それぞれにモルフォロジー グラデーションを適用し、それぞれを Otsu で 2 値化し (自動であり、比較的良好であり、簡単に入手できるため)、n 個のバイナリ チャネルを加算して 1 つに結合します。形態学的勾配は、強いエッジ (ノイズを含む) に対して高い応答を示し、2 値化ステップはそれらを維持します。次に、小さすぎるコンポーネントを削除し、間引きを行って 1 ピクセル幅のエッジを取得します。これらの手順を実行した後、サンプル画像で得られるものは次のとおりです。

ここに画像の説明を入力 ここに画像の説明を入力

f = Import["http://www.caughtinthefire.com/wp-content/uploads/2009/03/\
     fireworks-pixelate-02.gif"]
split = Binarize[ImageSubtract[Dilation[#, 1], Erosion[#, 1]]] & /@ 
  ColorSeparate[f, "RGB"]
thin = Thinning[SelectComponents[Fold[ImageAdd, split[[1]], split[[2 ;;]]], 
  "Count", # > 10 &]]

次に、この細線化されたバイナリ イメージの線を検出します。画像がピクセル化されると、多くの長方形の領域が形成されることが期待されますが、これらの長方形の領域を実際に形成できるという保証はありません。できると仮定すると、これらの各領域を接続されたコンポーネントと見なすことができます。次に、単純成分分析を次のように実行すると、凸包の面積と境界ボックスの面積の比率がある値よりも大きい場合、この面積は長方形の面積になります。長方形の領域が多くなる場合は、画像がピクセル化されていると言います (しかし、実際にはそのようなことを言う自信はありません)。次に、検出された線が重ねられた元の画像が表示されます。右側には、比率 > 95% を使用して前述の分析を検討した後に残っている連結成分 (黒ではない点) が表示されます。この場合、合計で 542 個の接続されたコンポーネントがあり、483 個に減少しました。これは、コンポーネントのほぼ 90% が長方形であることを意味します。残りのコンポーネントの領域を考慮したり、この分析を他の分析と組み合わせたりすることもできますが、ここでは行いません。

ここに画像の説明を入力 ここに画像の説明を入力

lines = ImageLines[thin, 0.05, Method -> "RANSAC"];
Show[f, Graphics[{Thick, Blue, Line /@ lines}]] (* The left image above. *)
blank = Image[ConstantArray[255, Reverse@ImageDimensions[thin]]];
blankcc = ImagePad[Binarize[Image[Show[blank, 
  Graphics[{Thick, Black, Line /@ lines}]]]], 1, Black]
ccrect = SelectComponents[MorphologicalComponents[blankcc], {"BoundingBoxArea", 
  "ConvexArea"}, #2/#1 > 0.95 &];
Colorize[ccrect, ColorFunction -> "DarkRainbow"] (* The right image above. *)

これは、「ピクセル化」の兆候です。

他の画像を考慮した他の結果を次に示します。これは常に、次の順序で 3 つの画像のシーケンスです: オリジナル、何も変更しない上記の結果、線検出のしきい値を変更した後の上記の結果。

すべてが長方形として検出されました。しかし、ここではライン検出のしきい値が0.05高すぎます。それを下げてから0.01、コンポーネントをより適切に分割します。

ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力

次に、予想外の画像を検討します。そのため、コンポーネントはほとんどありません。より多くの長方形コンポーネントを提供するライン検出のしきい値がないため、3 番目のイメージは空です (または、コンポーネントが残っていないため、完全に黒になります)。

ここに画像の説明を入力 ここに画像の説明を入力

最後に、正方形を回転させたピクセレーションです。次の画像を生成するプロセスは、サンプル画像で使用されているものとは異なる可能性がありますが、私は作成者ではないのでわかりません。右の画像は、ラインのしきい値を に上げた結果です0.08。ここでの問題は、領域が比較的大きいことです。これは、ピクセル化された画像の検出には考慮しません。

ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力

于 2013-01-20T15:07:33.127 に答える