OpenCV を使用した画像の二値化とグレースケール変換

OpenCV を使用した画像の二値化とグレースケール変換

関連概念

バイナリ画像とは、2 つの色 (通常は黒と白) のみを含む画像です。バイナリ画像では、各ピクセルは 0 (黒) または 255 (白) のいずれかであり、中間のグレー レベルはありません。

バイナリ画像は 2 つの色のみで構成されているため、画像処理アルゴリズムがよりシンプルかつ高速になり、画像処理と分析のプロセスを簡素化するために主に使用されます。たとえば、テキスト認識やバーコード読み取りなどのアプリケーションでは、バイナリ画像を使用すると画像処理と認識プロセスが大幅に簡素化されます。

バイナリ画像は、閾値セグメンテーション、反復閾値セグメンテーション、大津閾値法など、さまざまな方法で生成できます。これらの方法では通常、元の画像のピクセル値をしきい値と比較し、比較結果に基づいてピクセルを黒または白に設定します。

バイナリ画像の生成は、画像の処理と分析のプロセスを簡素化するために、コンピューター ビジョンや画像処理の分野でよく使用されます。

グレースケール画像は、ピクセルごとに 1 つの色のみがサンプリングされた画像で、通常は最も暗い黒から最も明るい白までのグレースケールとして表示されます。グレースケール画像はバイナリ画像とは異なります。コンピュータグラフィックスの分野では、バイナリ画像には黒と白の 2 色しかありませんが、グレースケール画像には黒と白の間に多くのレベルの色深度があります。

グレースケール画像は通常、各ピクセルの明るさを測定することによって取得されます。表示に使用されるグレースケール画像は通常、サンプルされたピクセルあたり 8 ビットの非線形スケールで保存されるため、256 レベルのグレーになります。

グレースケール画像は、カラー チャネルが 1 つしか含まれていないため、アルゴリズムが単純かつ高速になり、画像処理および分析プロセスを簡素化するために、画像処理でよく使用されます。

「カラー画像」カラー画像は、通常、赤、緑、青の 3 つのカラー チャネルで構成される色情報を表示できる画像です。各チャネルの色の強度は 0 から 255 の範囲で、0 はその色がまったく存在しないことを表し、255 はその色の完全な彩度を表します。異なる強度の 3 つのチャネルを組み合わせることで、ほぼすべての色を実現できます。

カラー画像は、デジタル画像処理とコンピュータービジョンの一般的な形式であり、写真、ビデオ、アニメーション、Web デザインで広く使用されています。デジタル画像処理では、3 つのカラー チャネルを同時に処理する必要があるため、カラー画像の処理と分析は通常、グレースケール画像よりも複雑になります。

カラー画像の利点は、色情報を表示でき、現実世界をよりリアルに反映できることです。ただし、カラー画像は通常、より多くの保存スペースと処理時間が必要となるため、グレースケール画像よりも処理速度が遅くなります。

イメージグレースケールは、カラーイメージをグレースケールイメージに変換するプロセスです。グレースケール画像では、カラー画像の赤、緑、青の 3 つのチャネルではなく、各ピクセルに 1 つのグレースケール値のみが含まれます。グレースケール画像には明るさの情報のみが含まれ、色情報は含まれていないため、画像処理や分析を簡素化するためによく使用されます。

グレースケールの利点は、カラー画像と比較して、メモリ使用量が少なく、実行速度が速いことです。また、視覚的なコントラストを高め、対象領域を強調表示できます。グレースケールの応用分野には、画像処理、コンピュータービジョン、パターン認識などの分野が含まれます。

グレースケール画像はバイナリ画像の特殊なケースであり、しきい値を比較することでピクセルが黒または白に設定されます。グレースケール処理には、最大法、平均法、加重平均法の 3 つの一般的な方法が使用されます。最大値法は、R、B、G の 3 つの成分のうち、最も値が大きい成分の値を直接取得します (0 が最小値、255 が最大値と見なされます)。平均値法は、R、B、G の 3 つの成分の値の平均を取得します。加重平均法は、人間の目のさまざまな色に対する感度に基づいて、さまざまな色チャネルに異なる重みを割り当てます。

画像の二値化とは、画像上のピクセルのグレースケール値を 0 または 255 に設定するプロセスであり、画像全体を明確な白黒で表示するプロセスです。バイナリ画像のデータ量が大幅に削減され、対象の輪郭が強調されます。バイナリ画像を取得するには、まず画像をグレースケール化し、次に適切なしきい値を使用して 256 の明るさレベルのグレースケール画像を選択し、画像の全体的な特徴とローカルな特徴を反映できるバイナリ画像を取得します。しきい値以上のグレースケールを持つすべてのピクセルは、特定のオブジェクトに属すると判断され、そのグレースケール値は 255 になります。それ以外の場合、これらのピクセルはオブジェクト領域から除外され、グレースケール値は 0 になり、背景または例外的なオブジェクト領域を示します。

最も一般的に使用される二値化法には、単純二値化法、平均法、二峰性法、OTSU 法などがあります。

2 値化は、画像セグメンテーションの最も簡単な方法の 1 つであり、コンピューター ビジョンの分野で広く使用されています。

グレースケール方式

  • 最大方式: カラー画像内の 3 成分の明るさの最大値をグレースケール画像のグレースケール値として使用します。

写真

  • 平均値法: カラー画像内の 3 つの明るさ成分を平均してグレースケール値を取得します。

写真

  • 加重平均方式: R、G、B の 3 つのチャネルに対する人間の目の感度に応じて、一定の重みに従って加重平均してグレースケール値を取得します。

写真

  • 浮動小数点グレースケール方式: 赤、緑、青のカラー チャネルに異なる浮動小数点の重みを掛け合わせ、RGB の重みの合計が 1 になるようにして、グレースケール値を取得します。

写真

  • 整数グレースケール方式: 浮動小数点演算を避け、整数演算を使用して、RGB の重みの合計が 100 になるようにグレースケール値を取得します。

写真

  • シフトグレースケール方式: シフト計算は整数グレースケール方式よりも高速です。

写真

  • シングル チャネル方式: 緑のみがグレー値として取得されます。

写真

グレースケール方式の例:

 //进行灰度mBitmap?.run { val bitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888) val srcMat = Mat() val dstMat = Mat() Utils.bitmapToMat(this, srcMat) Imgproc.cvtColor(srcMat, dstMat, Imgproc.COLOR_BGRA2GRAY) Utils.matToBitmap(dstMat, bitmap) runOnUiThread { mBinding.ivImage.setImageBitmap(bitmap) } srcMat.release() dstMat.release() }

写真

二値化法

  • グローバルしきい値設定: この方法では、特定のしきい値を超える明るさのピクセルは画像全体で前景 (白) としてマークされ、しきい値を下回る明るさのピクセルは背景 (黒) としてマークされると想定されます。
  • Otsu しきい値設定: これはヒストグラムに基づく適応しきい値選択アルゴリズムであり、使用されるしきい値はターゲットと背景の差を最大化できます。
  • ローカルしきい値方式: この方式は、グローバルしきい値方式のように画像全体を前景と背景に分割するのではなく、各ピクセルの周囲の明るさの変化に基づいて前景に属するか背景に属するかを判断します。この方法は通常、照明が不均一、ノイズが多い、テクスチャが粗いなどの状況で画像を二値化するために使用されます。
  • 適応しきい値設定: この方法では、各ピクセルのしきい値を、その近傍のピクセルの平均または加重平均に関連する値に設定します。この方法は通常、グレースケール画像から何らかの特殊な特徴を抽出する必要がある場合に使用されます。
  • 形態学的演算に基づくローカル二値化法: この方法はしきい値法に基づいており、画像のローカル特性をより適切に反映するために、画像のさまざまな領域に異なるしきい値を設定します。
  • クラスター分析に基づく二値化方法: この方法では、ピクセルのグレースケール値を 2 つのクラスターに分割し、2 つのクラスターの平均をそれぞれ計算し、その平均を処理のしきい値として使用します。
  • エッジ検出に基づく二値化方法: この方法では、画像内のエッジを検出した後、エッジ ピクセルを白に、その他のピクセルを黒に設定して、画像の二値化を実現します。

OpenCV では、しきい値分割の threshold() 関数、カラー画像分割の inRange() 関数、エッジ検出の Canny() 関数を使用して画像の二値化を実現できます。

OpenCV で最も簡単な実装方法は、まず画像をグレースケール化し、次にグレースケール画像内の各ピクセルを走査し、そのピクセル値が固定しきい値より大きいかどうかに応じて、出力画像内の対応する位置のピクセルに異なる値を割り当てることです。式は次のとおりです。

写真

二値化方法の例:

 mBitmap?.run { val bitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888) //先灰度val srcMat = Mat() val dstMat = Mat() Utils.bitmapToMat(this, srcMat) Imgproc.cvtColor(srcMat, dstMat, Imgproc.COLOR_BGRA2GRAY) val resultMat = Mat() Imgproc.threshold(dstMat, resultMat, 100.0, 255.0, Imgproc.THRESH_BINARY) Utils.matToBitmap(resultMat, bitmap) runOnUiThread { mBinding.ivImage.setImageBitmap(bitmap) } srcMat.release() dstMat.release() resultMat.release() }

写真

完全な例

<?xml versinotallow="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".activity.TestActivity"> <ImageView android:id="@+id/iv_image" android:layout_width="match_parent" android:layout_height="300dp" android:scaleType="centerCrop" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:orientation="horizontal"> <Button android:id="@+id/btn_load" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="加载图片" android:textSize="16sp" /> <Button android:id="@+id/btn_gray" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_weight="1" android:text="图片灰度化" android:textSize="16sp" /> <Button android:id="@+id/btn_binarization" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_weight="1" android:text="图片二值化" android:textSize="16sp" /> </LinearLayout> </LinearLayout>
 class TestActivity : AppCompatActivity() { private val TAG = MainActivity::class.java.simpleName private lateinit var mBinding: ActivityTestBinding private var mBitmap: Bitmap? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mBinding = ActivityTestBinding.inflate(layoutInflater) setContentView(mBinding.root) //初始化OpenCV val initState = OpenCVLoader.initLocal() Log.d(TAG, "onCreate: OpenCV初始化$initState") mBinding.btnLoad.setOnClickListener { val intent = Intent() intent.setType("image/*") intent.setAction(Intent.ACTION_GET_CONTENT) startActivityForResult(intent, 20240104) } mBinding.btnGray.setOnClickListener { if (mBitmap == null) { return@setOnClickListener } //进行灰度mBitmap?.run { val bitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888) val srcMat = Mat() val dstMat = Mat() Utils.bitmapToMat(this, srcMat) Imgproc.cvtColor(srcMat, dstMat, Imgproc.COLOR_BGRA2GRAY) Utils.matToBitmap(dstMat, bitmap) runOnUiThread { mBinding.ivImage.setImageBitmap(bitmap) } srcMat.release() dstMat.release() } } mBinding.btnBinarization.setOnClickListener { if (mBitmap == null) { return@setOnClickListener } mBitmap?.run { val bitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888) //先灰度val srcMat = Mat() val dstMat = Mat() Utils.bitmapToMat(this, srcMat) Imgproc.cvtColor(srcMat, dstMat, Imgproc.COLOR_BGRA2GRAY) val resultMat = Mat() Imgproc.threshold(dstMat, resultMat, 100.0, 255.0, Imgproc.THRESH_BINARY) Utils.matToBitmap(resultMat, bitmap) runOnUiThread { mBinding.ivImage.setImageBitmap(bitmap) } srcMat.release() dstMat.release() resultMat.release() } } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == 20240104 && resultCode == RESULT_OK && data != null) { data.data?.run { mBitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(this)) } mBitmap?.run { mBinding.ivImage.setImageBitmap(this) } } } }

要約する

画像の二値化は、画像内のピクセルを 0 または 255 に設定して白黒効果を実現するプロセスです。適切なしきい値を選択することで、グレースケール画像内のピクセルを 2 つのカテゴリに分類できます。1 つは前景 (ターゲット)、もう 1 つは背景と見なされます。これにより、対象の輪郭を強調しながら画像データの量を削減できます。

グレースケーリングは、カラー画像をグレースケール画像に変換するプロセスです。グレースケール画像では、カラー画像の赤、緑、青の 3 つのチャネルではなく、各ピクセルに 1 つのグレースケール値のみが含まれます。グレースケール画像には明るさの情報のみが含まれ、色情報は含まれていないため、画像処理や分析を簡素化するためによく使用されます。

グレースケール画像の各ピクセルは 8 ビットで表すことができるため、グレースケール値は 0 ~ 255 になります。バイナリ画像では、ピクセルには黒 (0) と白 (255) の 2 つの状態しかありません。

二値化はグレースケール画像を白黒の二値画像に変換するプロセスであり、グレースケーリングはカラー画像をグレースケール画像に変換するプロセスです。 OpenCV では、さまざまなしきい値処理方法を使用して、画像の二値化とグレースケール化を実現できます。

<<:  2023 年のテクノロジー業界の最高、最悪、そして最も醜い出来事

>>:  デザイナーに必須の AI ツール 11 選

ブログ    

推薦する

...

強化学習の起源:迷路を歩くネズミから人間に勝つAlphaGoまで

強化学習となると、多くの研究者のアドレナリンが抑えきれないほど湧き上がります!これは、ゲーム AI ...

生産効率が50%アップ!ファーウェイはAI機能を活用して大東コイルのデジタル変革を推進し、コスト削減と効率向上に貢献している。

デジタル変革は、現在の企業、特にハイテクの伝統的な製造業の主なテーマとなっています。人工知能、クラウ...

Google 創設者が正式に LLM 戦争に復帰!ジェミニの開発を導く、OpenAIとMetaとの戦いが迫る

4年前に辞任したGoogleの共同創設者がついに復帰!ウォール・ストリート・ジャーナルの報道によると...

SSDエラー訂正アルゴリズムの過去と現在

エラー訂正コード (ECC) は、送信プロセス中にエラーが発生した後に受信側でエラーを検出して訂正で...

...

クールなデュオ: AI が金融テクノロジーの進化にどのように役立つかを示す 6 つのケース スタディ

中国では、口座間の送金、銀行ローンの申請、取引の実行にインターネットを利用することが住民にとって日常...

中国の自動運転が新たなブレークスルーをもたらす:百度世界2020のCCTV生中継で完全無人運転を体験

中国の自動運転は新たな進歩を遂げ、無人運転の時代が到来した。 9月15日、百度はCCTVニュースと提...

人間の運転、交通事故の最大の欠陥 | 自動運転車の交通安全に関する白書が発表

今年の自動運転業界は商用化がキーワードです。年末に、百度、中国自動車技術研究センター、同済大学が共同...

人工知能は非常に人気があります。PULSE は低品質のモザイク画像を保存し、数秒で高解像度の画像に変換できます。

[51CTO.com オリジナル記事] モザイクとはどういう意味ですか?従来のモザイクは、主に映画...

2020 年の CIO にとっての 5 つの戦略的優先事項

ヘルスケア、小売、テクノロジー業界の IT リーダーが 2020 年の戦略的優先事項を共有します。ヒ...

自動運転:最も安全ではないが、より安全

「九章」量子コンピューティングのプロトタイプ、「天極」脳型チップ、国内最大直径のシールドマシン「景華...

5四半期連続で前年同期比で減少: AIはデルの危機を逆転できるか?

企業の時代はなく、時代の企業だけがある!新たなトレンドに直面しても、古い大手企業は反応が遅く、固定観...