2025.09.07
RGBをHSVに変換する その1
RGBをHSVに変換するソースコードについて
ここでは、色を表現するRGBの値をHSVに変換するJavaソースコードについて詳しく説明します。ソースコードの概要は以下の通りです。
②RGBの値をキーボードで入力
RGBの値をそれぞれキーボードで入力します。値の範囲は0~255です。
このソースコードでは、入力した値のチェックは行いません。数字以外の値や、0~255の範囲外の値を入力した場合、エラーまたは正しくない計算結果が出力されます。
③HSVの値を計算
④HSVの計算結果を出力
計算した色相H、彩度S、明度Vの値をprintlnメソッドでコンソール出力します。
Javaソースコード
キーボードで入力したRGBの値でHSVを計算するJavaソースコードです。
RGBtoHSV.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
import java.util.Scanner; public class RGBtoHSV { // 0.0に近い値を定義(値は任意) final static double E = 0.0000000000000000001; // RGBの値から色相Hを求めるメソッド(RGBの範囲チェックはしません) // rとgとbの範囲は0.0~1.0 // 戻り値の範囲は0.0~360.0 private static double rgb2h( double r, double g, double b ) { // RGBの最小値cmin、最大値cmaxを求める double cmin = Math.min( r, Math.min( g, b ) ); double cmax = Math.max( r, Math.max( g, b ) ); // 色相hの計算 double h; if ( E > Math.abs( cmin - cmax ) ) h = 0.0; // RGBの値が全て同じ else { if ( E > Math.abs( r - cmax ) ) h = 60.0 * ( g - b ) / ( cmax - cmin ); // Rが最大値の場合 else { if ( E > Math.abs( g - cmax ) ) h = 60.0 * ( b - r ) / ( cmax - cmin ) + 120.0; // Gが最大値の場合 else h = 60.0 * ( r - g ) / ( cmax - cmin ) + 240.0; // Bが最大値の場合 } } // 計算したhがマイナスの場合、360を足してプラスにする if ( 0.0 > h ) h += 360.0; // 計算した色相hを戻す return h; } // RGBの値から彩度Sを求めるメソッド(RGBの範囲チェックはしません) // rとgとbの範囲は0.0~1.0 // 戻り値の範囲は0.0~1.0 private static double rgb2s( double r, double g, double b ) { // RGBの最小値cmin、最大値cmaxを求める double cmin = Math.min( r, Math.min( g, b ) ); double cmax = Math.max( r, Math.max( g, b ) ); // 彩度sを計算 double s; if ( E > Math.abs( cmax ) ) s = 0.0; // cmaxが0.0の場合 else s = ( cmax - cmin ) / cmax; // 計算した彩度sを戻す return s; } // RGBの値から明度Vを求めるメソッド(RGBの範囲チェックはしません) // rとgとbの範囲は0.0~1.0 // 戻り値の範囲は0.0~1.0 private static double rgb2v( double r, double g, double b ) { // RGBの最大値cmaxを求める double cmax = Math.max( r, Math.max( g, b ) ); // 明度vを計算 double v = cmax; // 計算した明度vを戻す return v; } // メインメソッド public static void main( String[] args ) { // Scannerを作成 Scanner scan = new Scanner( System.in ); // Rの値を入力 System.out.println( "Rの値をを入力してください(0-255)" ); int r = scan.nextInt(); // Gの値を入力 System.out.println( "Gの値をを入力してください(0-255)" ); int g = scan.nextInt(); // Bの値を入力 System.out.println( "Bの値をを入力してください(0-255)" ); int b = scan.nextInt(); // rgbの値を0.0~1.0に変換 double rd = (double)r / 255.0; double gd = (double)g / 255.0; double bd = (double)b / 255.0; // 色相Hの計算 double h = rgb2h( rd, gd, bd ); // 彩度Sの計算 double s = rgb2s( rd, gd, bd ); // 明度Vの計算 double v = rgb2v( rd, gd, bd ); // 結果を出力 System.out.println( "R : " + r ); System.out.println( "G : " + g ); System.out.println( "B : " + b ); System.out.println(); System.out.println( "色相H : " + h ); System.out.println( "彩度S : " + s ); System.out.println( "明度V : " + v ); } }
実行結果
コンパイル ソースコードが「ANSI」の場合
C:\talavax\javasample>javac -encoding sjis RGBtoHSV.java
コンパイル ソースコードが「UTF-8」の場合
C:\talavax\javasample>javac RGBtoHSV.java
実行
C:\talavax\javasample>java RGBtoHSV
Rの値をを入力してください(0-255) 255 Gの値をを入力してください(0-255) 0 Bの値をを入力してください(0-255) 0 R : 255 G : 0 B : 0 色相H : 0.0 彩度S : 1.0 明度V : 1.0
キーボードでR=255、G=0、B=0を入力して、HSVを計算した結果が出力されています。
Javaソースコードの解説
ここでは、Javaソースコードを上から順番に解説しています。
001
import java.util.Scanner;
003
public class RGBtoHSV {
004 005
// 0.0に近い値を定義(値は任意) final static double E = 0.0000000000000000001;
007 008 009 010 011
// RGBの値から色相Hを求めるメソッド(RGBの範囲チェックはしません) // rとgとbの範囲は0.0~1.0 // 戻り値の範囲は0.0~360.0 private static double rgb2h( double r, double g, double b ) {
012 013 014
// RGBの最小値cmin、最大値cmaxを求める double cmin = Math.min( r, Math.min( g, b ) ); double cmax = Math.max( r, Math.max( g, b ) );
Math.minメソッド
public static int Math.min( int a, int b ) public static long Math.min( long a, long b ) public static float Math.min( float a, float b ) public static double Math.min( double a, double b )
・2つの値のうち小さい方を返します。 パラメータ a : 1つめの値 b : 2つめの値 戻り値 aとbのうち、小さい値
Math.maxメソッド
public static int Math.max( int a, int b ) public static long Math.max( long a, long b ) public static float Math.max( float a, float b ) public static double Math.max( double a, double b )
・2つの値のうち大きい方を返します。 パラメータ a : 1つめの値 b : 2つめの値 戻り値 aとbのうち、大きい値
016 017
// 色相hの計算 double h;
019 020
if ( E > Math.abs( cmin - cmax ) )
h = 0.0; // RGBの値が全て同じ
cminとcmaxの値が同じ場合、色相hに0.0を代入しています。
cminとcmaxが同じかどうかは、cminとcmaxの差の絶対値が、0.0とみなす値を格納した変数Eより小さいという条件で判定しています。
Math.absメソッド
public static int Math.abs( int a ) public static long Math.abs( long a ) public static float Math.abs( float a ) public static double Math.abs( double a ) public static int Math.abs( byte a ) public static int Math.abs( short a )
・引数aに指定した数値の絶対値を返します。 パラメータ a : 絶対値を求めたい数値 戻り値 aの絶対値を返します。 戻りの変数型は、基本的に引数と同じ変数型と考えてよいです。
021 022 023
else {
if ( E > Math.abs( r - cmax ) )
h = 60.0 * ( g - b ) / ( cmax - cmin ); // Rが最大値の場合
rとcmaxの値が同じ場合、色相hの値を以下の式で計算しています。
色相h = 60.0 * ( g - b ) / ( cmax - cmin )
024 025 026
else {
if ( E > Math.abs( g - cmax ) )
h = 60.0 * ( b - r ) / ( cmax - cmin ) + 120.0; // Gが最大値の場合
gとcmaxの値が同じ場合、色相hの値を以下の式で計算しています。
色相h = 60.0 * ( b - r ) / ( cmax - cmin ) + 120.0
027 028
else
h = 60.0 * ( r - g ) / ( cmax - cmin ) + 240.0; // Bが最大値の場合
bとcmaxの値が同じ場合、色相hの値を以下の式で計算しています。
色相h = 60.0 * ( r - g ) / ( cmax - cmin ) + 240.0
032 033
// 計算したhがマイナスの場合、360を足してプラスにする
if ( 0.0 > h ) h += 360.0;
計算したhがマイナスの場合、360.0を足してプラスの値にしています。
035 036
// 計算した色相hを戻す return h;
040 041 042 043 044
// RGBの値から彩度Sを求めるメソッド(RGBの範囲チェックはしません) // rとgとbの範囲は0.0~1.0 // 戻り値の範囲は0.0~1.0 private static double rgb2s( double r, double g, double b ) {
045 046 047
// RGBの最小値cmin、最大値cmaxを求める double cmin = Math.min( r, Math.min( g, b ) ); double cmax = Math.max( r, Math.max( g, b ) );
049 050
// 彩度sを計算 double s;
052 053 054 055
if ( E > Math.abs( cmax ) )
s = 0.0; // cmaxが0.0の場合
else
s = ( cmax - cmin ) / cmax;
cmaxが0.0の場合、変数sに0.0を代入しています。0.0でない場合以下の式で計算しています。
彩度s = ( cmax - cmin ) ÷ cmax
057 058
// 計算した彩度sを戻す return s;
062 063 064 065 066
// RGBの値から明度Vを求めるメソッド(RGBの範囲チェックはしません) // rとgとbの範囲は0.0~1.0 // 戻り値の範囲は0.0~1.0 private static double rgb2v( double r, double g, double b ) {
067 068
// RGBの最大値cmaxを求める double cmax = Math.max( r, Math.max( g, b ) );
070 071
// 明度vを計算 double v = cmax;
073 074
// 計算した明度vを戻す return v;
078 079
// メインメソッド public static void main( String[] args ) {
080 081
// Scannerを作成
Scanner scan = new Scanner( System.in );
標準入力System.inを使って、Scannerクラスの scanを初期化しています。
083 084 085
// Rの値を入力 System.out.println( "Rの値をを入力してください(0-255)" ); int r = scan.nextInt();
nextIntメソッドで、キーボードから入力された1行を読み取り、その値をint型の変数rに代入しています。
ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数rに格納されます。
キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。
087 088 089
// Gの値を入力 System.out.println( "Gの値をを入力してください(0-255)" ); int g = scan.nextInt();
nextIntメソッドで、キーボードから入力された1行を読み取り、その値をint型の変数gに代入しています。
ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数gに格納されます。
キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。
091 092 093
// Bの値を入力 System.out.println( "Bの値をを入力してください(0-255)" ); int b = scan.nextInt();
nextIntメソッドで、キーボードから入力された1行を読み取り、その値をint型の変数bに代入しています。
ここで、入力待ち状態になり、Enterキーが押されるまでに入力した値が変数bに格納されます。
キーボードの"Ctrl"キーを押しながら"C"を押すと強制終了します。
096 097 098 099
// rgbの値を0.0~1.0に変換 double rd = (double)r / 255.0; double gd = (double)g / 255.0; double bd = (double)b / 255.0;
0~255で入力したr、g、bを255.0で割って、0.0~1.0に変換しています。
101 102
// 色相Hの計算 double h = rgb2h( rd, gd, bd );
104 105
// 彩度Sの計算 double s = rgb2s( rd, gd, bd );
107 108
// 明度Vの計算 double v = rgb2v( rd, gd, bd );
111 112 113 114
// 結果を出力 System.out.println( "R : " + r ); System.out.println( "G : " + g ); System.out.println( "B : " + b );
入力したRとGとBをprintlnメソッドでコンソール出力しています。
116
System.out.println();
改行しています。
118 119 120
System.out.println( "色相H : " + h ); System.out.println( "彩度S : " + s ); System.out.println( "明度V : " + v );
計算結果の色相Hと、彩度S、明度Vをprintlnメソッドでコンソール出力しています。
このソースコードでは、rgb2hメソッドとrgb2sメソッドの中でrgbの最小値cminと最大値cmaxを計算しています。また、rgb2vメソッドの中では最大値cmaxを計算しています。
HSVの値を同時に計算する場合は、各メソッドにあらかじめrgbから求めたcminとcmaxを引数で渡せば計算コストが下がります。
HSVに関するコンテンツ
「HSV」に関係があるコンテンツをまとめています。
- アルファ値(透過)
- 2値化
- 2値化 その2
- 色見本
- 光と色の3原色
- テーブルによる色変換 その1
- カラーマップ
- 色をARGB値に分解
- 画像の新規作成
- 画像の新規作成 その2
- 縁付き画像変換
- エッジ(境界)検出
- 画像の2倍拡大
- グラデーション画像(横方向)
- グラデーション画像(放射状)
- グラデーション画像(4隅の色)
- グレースケール変換
- より自然なグレースケール変換
- 8ビットのグレースケールに変換
- HSV色空間について
- 画像の色
- 画像ファイル形式
- 画像処理とは
- RGBの平均値
- インデックスカラー
- 画像をセピア色にする
- 画像の一部を切り出す
- 画像を操作するクラスの作成
- N値化
- 画像の色反転
- ノイズ画像の作成
- 画像にノイズを加える
- 正確な割合のノイズ画像作成
- 指定色の画素数取得
- 画像をぼかす
- 空間フィルタリング
- 非圧縮