Java OpenCV Lv4 〜画像の中身をみてみる〜

イントロダクション

今回はPNGファイルの中身をのぞいて、プログラムで線を引く描画処理をしてみます。今までやってきたことは下のリンク参照で。。。

  1. Java OpenCV 環境セットアップ(on Mac)
  2. Java OpenCv Lv1 〜入門: 写真の表示〜
  3. Java OpenCV Lv2 〜画像を表示する〜
  4. Java OpenCV Lv3 〜画像の平滑化(smooth())〜
  5. Java OpenCV Lv3 〜画像にガウシアンフィルタ(GaussianBlur())〜
  6. Java OpenCV Lv3 〜画像に中央値フィルタ(medianBlur())〜

しかし、画像がぼやけた感じになったのはわかったのですが、処理としては何をしているのかいまいちわかりませんでした。

なので、今回は画像の中身をみてみようと思います。

今回のポイント

  1. 画像データはどんなものなのか?
  2. 画像のデータを操作するということは、何をすることか?
  3. 色はどんなデータ?

今回使用するイメージ(アイコン)ファイルは下のようなものです。

一発目のイメージファイル

<likeEye.png>: 10 x 10

そして、下のようなコードをみてください

package jp.zenryoku.opencv;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import jp.zenryoku.opencv.view.ViewFrame;

/**
 * OpenCVで平滑化処理を行う。
 * 
 * @author takunoji
 * 2018/11/22
 */
public class OpenCVTest4 {

	static {
		// OpenCVのライブラリをロードする
		// static {~}はMainメソッドの開始前に起動する、起動するプログラムで1つ定義可能
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}
	/**
	 * メインメソッド、書き方は決まっている。
	 * イメージファイルを読み込んでぼかす Imgproc.blur()
	 * 
	 * @param argsプログラム引数
	 */
	public static void main(String[] args) {
		// ファイルの読み込み
		Mat src = Imgcodecs.imread(
				OpenCVTest4.class.getClass().getResource("/images/likeEye.png").getPath());
		System.out.println(src.dump());
// OpenCVTest3の一部をコメントアウト
//		// 出力用変数
//		Mat dst = new Mat();
//		// ブラーする、種知力用の変数に値をセットする→「参照渡し」
//		//Imgproc.blur(mat, source, new Size(2.0,2.0));
//		// 中央値フィルタ
//		Imgproc.medianBlur(src, dst, 7);
//		// 自作のJFrame拡張クラス
//		new ViewFrame(dst);
	}
}

前回のコードの一部をコメントアウトして、Matクラスのメソッドで読み込んだPNGファイルの中身をコンソール出力します。結果は下に

[  0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255;
 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255;
 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255;
 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255;
 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255;
 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255;
 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255;
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]

上の結果を見てみると、「;」で区切られた配列が10個あります。そして1行の配列長が30になっています。

二発目のイメージファイル

一発目のイメージファイルに線を一本引いてそれを表示したものです。




キャプチャーしたものを加工したので少し変ですが。。。一発目と同じ<10 x 10>のイメージです。

そして、中身のデータは以下。

[ 30,  30,  40, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255;
 255, 255, 255,  30,  30,  40, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
 255, 255, 255, 255, 255, 255,  30,  30,  40, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255;
 255, 255, 255,   0,   0,   0, 255, 255, 255,  30,  30,  40, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255;
 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255,  30,  30,  40, 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255;
 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255,  30,  30,  40, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255;
 255, 255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255,  30,  30,  40, 255, 255, 255, 255, 255, 255, 255, 255, 255;
 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255,  30,  30,  40, 255, 255, 255, 255, 255, 255;
   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,  30,  30,  40, 255, 255, 255;
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,  30,  30,  40]

初めの2個だけ赤い文字にしました。ちなにみ初めのソースと違う部分は以下の赤い字の部分。

今日の学習ポイント

// ファイルの読み込み
Mat src = Imgcodecs.imread(
	OpenCVTest4.class.getClass().getResource("/images/likeEye.png").getPath());
Point pt1 = new Point(0,0);
Point pt2 = new Point(10,10);
Imgproc.line(src, pt1, pt2, new Scalar(30, 30, 40));

System.out.println(src.dump());

出力した配列の中身は「1px目のR,G,B,2px....」と並んでいるようです。

[ 30, 30, 40, 255, 255, 255, 。。。

あと、線を引くときは「Imgproc.line()」を使用すれば良いことがわかりました。

ソースコードはGITからダウンロードできます。

余談

白い色は「255」で黒は「0」になっています。サンプルの画像とデータです。

関連ページ一覧

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseにCDTをインストール〜
  3. Setup OpenGL with Java〜JOGLを使う準備 for Eclipse〜
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)

Java OpenCV Lv3 〜画像に中央値フィルタ(medianBlur())〜

イントロダクション

前回、OpenCVを使ってイメージファイルから、文字列を取得するのを目標にOpenCVを学んできます。文字列を読み込むまでに機械学習も学ぶ(倒す)必要があるのでまずは、目の前の敵を倒します。今日の敵は「中央値フィルタ」

参考サイトはこちらです。そしてJavaDocAPI

実装

前回作成したコードの1行を変えるだけで実装は完了します。

/**
 * メインメソッド、書き方は決まっている。
 * イメージファイルを読み込んでぼかす Imgproc.blur()
 * 
 * @param argsプログラム引数
 */
public static void main(String[] args) {
	// ファイルの読み込み
	Mat mat = Imgcodecs.imread(
		OpenCVTest2.class.getClass().getResource("/images/Experience.png").getPath());
	// 出力用変数
	Mat source = new Mat();
	// ブラーする、種知力用の変数に値をセットする→「参照渡し」
	//Imgproc.blur(mat, source, new Size(2.0,2.0));
	// 中央値フィルタ
	Imgproc.medianBlur(src, dst, 7);
	// 自作のJFrame拡張クラス
	new ViewFrame(source);
}

上のコード赤字の部分が追加した行です。

<実行結果>



ま塩ノイズのような特異なノイズに対して効果的です.カーネルサイズは奇数でなければいけません

1行変えただけですからね(笑)。

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseにCDTをインストール〜
  3. Setup OpenGL with Java〜JOGLを使う準備 for Eclipse〜
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)

Java OpenCV Lv3 〜画像にガウシアンフィルタ(GaussianBlur())〜

イントロダクション

前回、OpenCVを使ってイメージファイルから、文字列を取得するのを目標にOpenCVを学んできます。文字列を読み込むまでに機械学習も学ぶ(倒す)必要があるのでまずは、目の前の敵を倒します。今日の敵は「ガウンシアンブラー?」

参考サイトはこちらです。そしてJavaDocAPI

実装

前回作成したコードの1行を変えるだけで実装は完了します。

/**
 * メインメソッド、書き方は決まっている。
 * イメージファイルを読み込んでぼかす Imgproc.blur()
 * 
 * @param argsプログラム引数
 */
public static void main(String[] args) {
	// ファイルの読み込み
	Mat mat = Imgcodecs.imread(
		OpenCVTest2.class.getClass().getResource("/images/Experience.png").getPath());
	// 出力用変数
	Mat source = new Mat();
	// ブラーする、種知力用の変数に値をセットする→「参照渡し」
	//Imgproc.blur(mat, source, new Size(2.0,2.0));
	// ガウシアンフィルタ
	Imgproc.GaussianBlur(mat, source, new Size(5, 5), 5.0);
	// 自作のJFrame拡張クラス
	new ViewFrame(source);
}

上のコード赤字の部分が追加した行です。

<実行結果>

見た目上、「何が違うの?」って感じですが、ボケ方が中心部と外側でボケ方が違います。

なんでも「注目画素との距離に応じて重みを変えるガウシアンカーネルを採用」するようで、白黒の雑音の除去に適しているようです。

簡単に終わってしまいました。

<余談>


DNSの設定が変わりWordPressにアクセスができなくなった経緯

昨日(2018/11/20)、このサイトにアクセスができなくなりました。

原因は、DNSの名前解決ができなくなっていたためです。

このブログをみてくれている人々にご迷惑をおかけしました。今後もブログを続けていくのでよろしくお願いいたします。

ちなみに、「DNSの名前解決ができなくなっていた」と記載しましたが経緯記載します。

  1. DNSにCNAMEレコードを追加
  2. 携帯で「zenryokuservice.com/wp」へのアクセスができなくなった
  3. 携帯で「takunoji.minim.ne.jp/wp」へのアクセスはできたが表示がいつもと違う
  4. 原因を探すが、わからないのでDNSプロバイダにログイン
  5. ネームサーバの名前が別のものに変わっていた

ここまでがブログにアクセスできなくなっていた原因でした。

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseにCDTをインストール〜
  3. Setup OpenGL with Java〜JOGLを使う準備 for Eclipse〜
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)

JavaDoc(クラスの使い方)

  1. JavaDoc 読解 〜 Filesクラス 〜
  2. Java Doc読解 BufferedReader
  3. Java Doc 読解〜BufferedWriter〜

OpenCv

  1. Java OpenCV 環境セットアップ(on Mac)
  2. Java OpenCv Lv1 〜入門: 写真の表示〜
  3. Java OpenCV Lv2 〜画像を表示する〜
  4. Java OpenCV Lv3 〜画像の平滑化(smooth())〜
  5. Java OpenCV Lv3 〜画像にガウシアンフィルタ(GaussianBlur())〜
  6. Java OpenCV Lv3 〜画像に中央値フィルタ(medianBlur())〜
  7. Java OpenCV Lv4 〜画像の中身をみてみる〜
  8. Java OpenCV Lv5 〜Matクラスで描画処理〜

Java OpenCV Lv3 〜画像の平滑化(smooth())〜

イントロダクション

前回は、Java Swingを使用してイメージファイルを表示しました。

次は、画像を加工して表示します。

参考サイトはこちらです。そしてJavaDocAPI

平滑化処理

<実行結果>

左のほうがSwingで表示したものです。ぼやけています。

Imgproc.blur(mat, source, new Size(10.0,10.0));

上の部分でぼやかしているのですが、いまいち理解できません。

Imgproc.blur(mat, source, new Size(2.0,2.0));

でやってみます。

Sizeの値が違うと、ボケ方も変わります。。。要するにSizeの値でボケ具合を調節できるということか。。。



次は、「ガウス〜」の処理をやります。

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseにCDTをインストール〜
  3. Setup OpenGL with Java〜JOGLを使う準備 for Eclipse〜
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)

 

OpenCv

  1. Java OpenCV 環境セットアップ(on Mac)
  2. Java OpenCv Lv1 〜入門: 写真の表示〜
  3. Java OpenCV Lv2 〜画像を表示する〜
  4. Java OpenCV Lv3 〜画像の平滑化(smooth())〜
  5. Java OpenCV Lv3 〜画像にガウシアンフィルタ(GaussianBlur())〜
  6. Java OpenCV Lv3 〜画像に中央値フィルタ(medianBlur())〜
  7. Java OpenCV Lv4 〜画像の中身をみてみる〜
  8. Java OpenCV Lv5 〜Matクラスで描画処理〜

Java OpenCV Lv2 〜画像を表示する〜

インントロダクション

今までJavaFXだとか、根深いビデオキャプチャの問題があるとかやってきましたが。。。

OpenCVを学ぶのにそんなのはほっといても良いことに気がつきました。

単純に画像を表示できればOK!

参考サイト

https://www.tutorialspoint.com/opencv/opencv_gui.htm

<今までこんなことをやってきました。(OpenCV編)>

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseにCDTをインストール〜
  3. Setup OpenGL with Java〜JOGLを使う準備 for Eclipse〜
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)

OpenCV

  1. Java OpenCV 環境セットアップ(on Mac)
  2. Java OpenCv Lv1 〜入門: 写真の表示〜
  3. Java OpenCV Lv2 〜画像を表示する〜
  4. Java OpenCV Lv3 〜画像の平滑化(smooth())〜

<実行結果>

<実装したコードにコメント>


<作成したコード>

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;

/**
 * @author takunoji
 *
 * 2018/11/18
 */
public class TrainOpenCV {
	static {
		// OpenCVライグラリ
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}
	public static void main(String[] args) {
		Mat image = Imgcodecs.imread(TrainOpenCV.class.getClass().getResource("/images/Experience.png").getPath());
		MatOfByte bytes = new MatOfByte();
		Imgcodecs.imencode(".png", image, bytes);
		byte[] b = bytes.toArray();
		InputStream in = new ByteArrayInputStream(b);
		BufferedImage buf = null;
		try {
			buf = ImageIO.read(in);
		} catch(IOException e) {
			e.printStackTrace();
		}
		// Create Swing Compoenent
		JFrame frame = new JFrame("Show Image");
		frame.getContentPane().add(new JLabel(new ImageIcon(buf)));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
}

明日から、こっちのコードでOpenCVの仕組みを学んでいこうと思います。

お疲れ様でした。