2016/06/14 公開
・画像にノイズを加える
乱数を使って指定の画像にノイズ画像を加える方法を解説します。ノイズが発生する割合をパーセントで指定することで、ノイズの密度を調整することができるようにします。
Noise2.java ← クリックしてダウンロードページに移動
001: import java.awt.image.BufferedImage; 002: import java.io.File; 003: import javax.imageio.ImageIO; 004: import java.io.IOException; 005: 006: public class Noise2 { 007: public static void main( String[] args ) { 008: boolean result; // 結果格納フラグ 009: double noiserate; // ノイズの割合 010: 011: // ファイル名 012: String inname, outname; 013: // 画像格納クラス 014: BufferedImage img = null; 015: 016: // 入力した引数が3つ以上かを調べる 017: if ( 3 > args.length ) { 018: // 入力した引数が3つ未満の場合、使用方法を表示する 019: System.out.println( 020: "Noise2 [入力JPEG名] [出力JPEG名] [ノイズの割合%]" ); 021: return; 022: } 023: 024: // 入力JPEG名をinnameに代入(拡張子".jpg"省略なし) 025: inname = args[ 0 ]; 026: // 出力JPEG名をoutnameに代入(拡張子".jpg"省略なし) 027: outname = args[ 1 ]; 028: 029: // 引数を変換し、ノイズの割合に代入 030: try { 031: noiserate = Double.valueOf( args[ 2 ] ); 032: } 033: catch( NumberFormatException ne ) 034: { 035: System.out.println( "引数が不正です" ); 036: return; 037: } 038: 039: // JPEGの読み込み 040: try { 041: // inname(入力JPEG)を読み込んでimgにセット 042: img = ImageIO.read( new File( inname ) ); 043: } catch (Exception e) { 044: // inname(入力JPEG)の読み込みに失敗したときの処理 045: e.printStackTrace(); 046: return; 047: } 048: 049: // 画像の色の持ち方をチェック 050: if ( BufferedImage.TYPE_3BYTE_BGR != img.getType() ) 051: { 052: System.out.println( "対応していないカラーモデルです!(" 053: + inname +")" ); 054: return; 055: } 056: 057: // ノイズ画像の作成 058: int x, y; 059: int width, height; 060: int r, g, b, color; 061: double rate; 062: 063: // 画像サイズの取得 064: width = img.getWidth(); 065: height= img.getHeight(); 066: 067: // ノイズを加える 068: for ( y = 0; y < height; ++ y ) { 069: for ( x = 0; x < width; ++ x ) { 070: // 乱数を発生 071: rate = Math.random() * 100.0; 072: 073: // ノイズ色にするかを判定 074: if ( noiserate > rate ) { 075: // ノイズとして白色を設定 076: r = 255; 077: g =255; 078: b =255; 079: 080: // r,g,bの色を合成 081: color = ( r << 16 ) + ( g << 8 ) + b; 082: 083: // 合成した色を(x,y)に設定 084: img.setRGB( x, y, color ); 085: } 086: } 087: } 088: 089: try { 090: // imgをoutname(出力JPEG)に保存 091: result = ImageIO.write( img, "jpeg", new File( outname ) ); 092: } catch ( Exception e ) { 093: // outname(出力JPEG)の保存に失敗したときの処理 094: e.printStackTrace(); 095: return; 096: } 097: 098: // 正常に終了 099: System.out.println( "正常に終了しました" ); 100: } 101: }
Noise2を実行
C:\talavax\javasample>java Noise2 sampleimage001_400x320.jpg noise2.jpg 20.0
1つ目の引数で元のJPEGファイル名、2つ目の引数でノイズを加えたJPEG画像ファイル名、3つ目の引数でノイズピクセルの発生率をパーセントで指定します。
実行結果
・元の画像(sampleimage001_400x320.jpg)
・ノイズを加えた画像(noise2.jpg)
ノイズを加えた画像(20%)
ここからは、このJavaソースコードを上から順番に解説していきます。
001: import java.awt.image.BufferedImage; 002: import java.io.File; 003: import javax.imageio.ImageIO; 004: import java.io.IOException; 005:
Javaのクラスライブラリの中から「java.awt.image.BufferedImage」と「java.io.File」と「javax.imageio.ImageIO」と「java.io.IOException」と「java.awt.image.RasterFormatException」というパッケージにあるクラスを、このプログラム内で使うために記述します。 この記述により、ImageIOクラスとBufferedImageクラスとRasterFormatExceptionが利用できるようになります。
006: public class Noise2 {
クラス名を、Noise2としています。
007: public static void main( String[] args ) {
このmainメソッドからプログラムを実行します。
008: boolean result; // 結果格納フラグ 009: double noiserate; // ノイズの割合 010: 011: // ファイル名 012: String inname, outname; 013: // 画像格納クラス 014: BufferedImage img = null;
このプログラムで使う変数を宣言しています。
016: // 入力した引数が3つ以上かを調べる 017: if ( 3 > args.length ) { 018: // 入力した引数が3つ未満の場合、使用方法を表示する 019: System.out.println( 020: "Noise2 [入力JPEG名] [出力JPEG名] [ノイズの割合%]" ); 021: return; 022: }
3つ以上の引数が与えられたかをチェックし、4つ未満の場合に、使い方のメッセージを表示し、returnによってmainメソッドを抜けています。
024: // 入力JPEG名をinnameに代入(拡張子".jpg"省略なし) 025: inname = args[ 0 ]; 026: // 出力JPEG名をoutnameに代入(拡張子".jpg"省略なし) 027: outname = args[ 1 ]; 028: 029: // 引数を変換し、ノイズの割合に代入 030: try { 031: noiserate = Double.valueOf( args[ 2 ] ); 032: } 033: catch( NumberFormatException ne ) 034: { 035: System.out.println( "引数が不正です" ); 036: return; 037: }
与えられた引数をそれぞれ、入力JPEGファイル名、出力JPEGファイル名、ノイズの割合を格納する変数に代入しています。
039: // JPEGの読み込み 040: try { 041: // inname(入力JPEG)を読み込んでimgにセット 042: img = ImageIO.read( new File( inname ) ); 043: } catch (Exception e) { 044: // inname(入力JPEG)の読み込みに失敗したときの処理 045: e.printStackTrace(); 046: return; 047: }
BufferedImageクラスのコンストラクタで、新しいBufferedImageを構築しています。
BufferedImageコンストラクタ
■新しい BufferedImage を構築します。 パラメータ width : 構築する画像の横ピクセル height : 構築する画像の縦ピクセル imageType : 構築する画像のイメージ形式
imgTypeで指定しているTYPE_INT_RGBは、整数型ピクセルにパックされた 8 ビット RGB 色成分によるイメージを表します。これを指定することで24ビットの画像を作成できます。
try { ~ } catchは、失敗する可能性がある処理を波括弧で囲み、その処理に失敗したときにcatch { ~ }の波括弧で囲まれた処理を実行するということです。この場合は、JPEGファイル名が不正であったり、存在していなかったり、フォーマットが違っているなどが原因で処理が失敗する可能性があります。処理が失敗するとreturnによってmainメソッドを抜けるようにしています。
049: // 画像の色の持ち方をチェック 050: if ( BufferedImage.TYPE_3BYTE_BGR != img.getType() ) 051: { 052: System.out.println( "対応していないカラーモデルです!(" 053: + inname +")" ); 054: return; 055: }
BufferedImageクラスのgetTypeメソッドで画像のイメージ型を取得しています。
BufferedImage.getTypeメソッド
■イメージ型を返します。 パラメータ なし 戻り値 BufferedImage のイメージ型を返します。
057: // ノイズ画像の作成 058: int x, y; 059: int width, height; 060: int r, g, b, color; 061: double rate;
063: // 画像サイズの取得 064: width = img.getWidth(); 065: height= img.getHeight();
画像の幅を変数width、高さを変数heightに代入しています。
067: // ノイズを加える 068: for ( y = 0; y < height; ++ y ) { 069: for ( x = 0; x < width; ++ x ) {
画像の中の全てのピクセルの座標を参照するループをつくっています。具体的には、変数yを0~height-1、変数xを0~width-1に変化させています。
070: // 乱数を発生 071: rate = Math.random() * 100.0;
乱数からパーセントを計算した値(0.0~99.999..)を変数rateに代入しています。Math.randomメソッドは、0.0~0.99999..の乱数を発生するので、その値に100.0を掛けることでパーセントを計算しています。
Math.randomメソッド
■乱数を返します。 パラメータ なし 戻り値 0.0以上、1.0未満の乱数
073: // ノイズ色にするかを判定 074: if ( noiserate > rate ) {
引数で指定したノイズの割合(noiserate)より、乱数から作成した値(rate)が小さければノイズと判定しています。この処理で、指定したノイズ割合を大きくすれば、ノイズの発生率が高くなるようにしています。
075: // ノイズとして白色を設定 076: r = 255; 077: g =255; 078: b =255; 079: 080: // r,g,bの色を合成 081: color = ( r << 16 ) + ( g << 8 ) + b;
083: // 合成した色を(x,y)に設定 084: img.setRGB( x, y, color );
色(変数color)を(x,y)に代入しています。
089: try { 090: // imgをoutname(出力JPEG)に保存 091: result = ImageIO.write( img, "jpeg", new File( outname ) ); 092: } catch ( Exception e ) { 093: // outname(出力JPEG)の保存に失敗したときの処理 094: e.printStackTrace(); 095: return; 096: }
BufferedImageクラスのimgのメモリ内のデータを、出力JPEG名の変数(outname)に格納されているファイル名で保存します。この場合は、JPEGファイル名が不正であったり、保存先のHDDなどが存在していなかったり、空き容量が少ないなどが原因で処理が失敗する可能性があります。
ImageIO.writeメソッド
■BufferedImageを画像ファイルに保存します。 パラメータ RenderedImage : 保存するRenderedImage formatName : 画像ファイルのフォーマット(png/jpeg/bmp/gifなど) output : Fileオブジェクト 戻り値 保存に成功するとtrue、失敗するとfalseを返します。
098: // 正常に終了 099: System.out.println( "正常に終了しました" );
全ての処理が正常終了すると、ここまで処理が実行されます。
■関連コンテンツ
光と色の3原色 | 光と色の3原色の考え方を解説 |
画像の色 | 画像の色について解説 |
画像ファイル形式 | 画像ファイル形式について解説 |
コマンドライン引数 | 外部からの値を受け取る方法について解説 |
ノイズ画像乱数を使ったノイズ画像の作成方法について解説しています。 |
|
正確な割合のノイズ画像乱数を使って正確な割合のノイズ画像を作成する方法を解説しています。 |
|
光と色の3原色光の3色(RGB)の混合と、インクの3色(CMY)の混合の考え方を説明しています。 |
|
画素画素とは、デジタル画像データを構成している色情報を持った点のことです。 |
|
for文繰り返し処理に使用するfor文をJavaのソースコードを使って説明しています。 |
|
乱数 randomMath.randomメソッドを使って乱数を発生する方法を解説します。指定範囲の乱数の発生方法も解説しています。 |
■新着情報
2022.07.07 | 外部プログラムの実行 | exeファイル実行 |
2022.07.06 | 完全数 | 6=1+2+3 |
■広告