この記事では、javaの例について説明して、色画像のメイン色を取得します。次のように、参照のために共有してください。
1:基本的なアイデア
RGBカラースペースのカラー画像については、プログラムを通じて画像のいくつかのメインカラーを何度も取得したいと考えています。ただし、一般的な画像では、色接合部でピクセル混合が達成されます。したがって、画像のピクセル値を直接スキャンすると、数百の異なる色の値が生じる可能性があります。実際、画像には3〜4色の色しかない場合があります。これらの混合色を削除し、これらの3〜4の主な色を正確に抽出する方法。一般的な画像の特性によれば、画像は同じ色の境界で異なる色の値を混合しません。画像のエッジ特性の1つと見なすことができます。したがって、これらの混合ピクセルの抽出物は、単純なエッジ勾配アルゴリズムに従って出力ピクセル値アレイを取得し、各ピクセル値をスキャンして、指定された半径パラメーターrの周りのピクセルを探し、センターピクセルのピクセル値に近いピクセルポイントの値を見つけます。スキャンが完了すると、ピクセル配列を出力し、次に線形にスキャンして、画像のメインカラーRGB値を取得することができます。
2:実装手順
1.画像配列を入力して、色画像をグレースケールします。
2。グレースケールの画像については、画像勾配を計算し、ここでSOBOLオペレーターを使用します。
3。ゼロ以外のピクセルポイントごとに、半径rの範囲内でスキャンし、ゼロの最も近い元のピクセル値を見つけます。
4.取得した配列をスキャンして、メイン色を取得します。
パラメーターrは、さまざまなアプリケーションシナリオに従って最も適切な値を見つけることです。理論的には、画像が大きいほどRの値が大きくなるはずです。そうしないと、アルゴリズムは不正確になります。
3:元の画像と操作効果
元の画像
アルゴリズムが実行された後、4つのメイン色が抽出されます
4:アルゴリズム実装ソースコード
public static bufferedimage removeblendpixels(bufferedimage image、int raidus){int width = image.getWidth(); int height = image.getheight(); int [] pixels = new int [width * height]; getRgb(画像、0、0、幅、高さ、ピクセル); // results resultの作成bufferedimage resultimg = createcompatibledestimage(image、null); setrgb(resultimg、0、0、幅、高さ、ピクセル); // results resultの作成bufferedimage resultimg = createcompatibledestimage(image、null); setrgb(resultimg、0、0、幅、高さ、ピクセル); //グレースケールとグラデーションバイト[] GrayData = getGrayData(ピクセル、幅、高さ); byte [] binarydata = getgrident(graydata、width、height); int index = 0; for(int row = 1; row <height -1; row ++){for(int col = 1; col <width -1; col ++){index = row * width+col; int pixel =(binarydata [index]&0xff); if(pixel> 0){// radiusスキャン操作int mindis = integer.max_value; int minrow = -1; int mincol = -1; int nr = 0; int nc = 0; int index2 = 0; for(int subrow = -raidus; subrow <= raidus; subrow ++){nr = row+subrow; if(nr <0 || nr> = height){続行; } for(int subcol = -raidus; subcol <= raidus; subcol ++){nc = col+subcol; if(nc <0 || nc> = width){継続; } index2 = nr * width + nc; int value =(binarydata [index2]&0xff); if(value == 0){int distance = distancolor(image.getRgb(nc、nr)、image.getrgb(col、row)); if(distance <mindis){mindis = distance; minrow = nr; mincol = nc; }}}} resultimg.setrgb(col、row、image.getrgb(mincol、minrow)); }}} return resultimg; } public static int distancolor(int rgb、int rgb2){// 1つのint r1 =(rgb >> 16)&0xff; int g1 =(rgb >> 8)&0xff; int b1 = rgb&0xff; // 2つのint r2 =(rgb2 >> 16)&0xff; int g2 =(rgb2 >> 8)&0xff; int b2 = rgb2&0xff; //距離int rr = r1 -r2; int gg = g1 -g2; int bb = b1 -b2; int sum =(int)math.sqrt(rr * rr + gg * gg + bb * bb);返品額; } public static byte [] getgraydata(int [] inpixels、int width、int height){// image grayscale byte [] outpixels = new byte [width * height]; int index = 0; for(int row = 0; row <height; row ++){int tr = 0、tg = 0、tb = 0; for(int col = 0; col <width; col ++){index = row * width+col; tr =(inpixels [index] >> 16)&0xff; tg =(inpixels [index] >> 8)&0xff; TB = inpixels [index]&0xff; int gray =(int)(0.299 * tr + 0.587 * tg + 0.114 * tb);アウトピクセル[index] =(byte)(gray&0xff); }} return outpixels; } public static byte [] getGrident(byte [] inpixels、int width、int height){byte [] outpixels = new byte [width * height]; int index = 0; for(int row = 0; row <height; row ++){int tr = 0; for(int col = 0; col <width; col ++){if(row == 0 || col == 0 ||(row == height -1)||(col == width -1)){index = row * width+col;アウトピクセル[index] =(byte)(0x00);続く; } int xg = 0、yg = 0; for(int sr = -1; sr <= 1; sr ++){for(int sc = -1; sc <= 1; sc ++){int nrow = row+sr; int ncol = col + sc; if(nrow <0 || nrow> = height){nrow = 0; } if(ncol <0 || ncol> = width){ncol = 0; } index = nrow * width + ncol; tr =(inpixels [index]&0xff); xg + = x_sobel [sr + 1] [sc + 1] * tr; yg + = y_sobel [sr + 1] [sc + 1] * tr; }} index = row * width + col; int g =(int)math.sqrt(xg * xg + yg * yg);アウトピクセル[index] =(byte)(clamp(g)&0xff); }} return outpixels; }定義する必要がある一定の値は次のとおりです。
public static final int [] [] x_sobel = new int [] [] {{-1、-2、-1}、{0、0、0}、{1、2、1}}; public static final int [] [] y_sobel = new int [] [] {{-1、0、1}、{-2、0、2}、{-1、0、1}}; public static final int block_pixel_radius = 5; Gradient AcquisitionはSOBOLオペレーターを使用します。メインカラーを取得するために処理後に緩衝オブジェクトをスキャンするためのコードは次のとおりです。
int width = result.getWidth(); int height = result.getheight(); map <integer、integer> colorindexmap = new Hashmap <integer、integer>(); for(int row = 0; row <height; row ++){for(int col = 0; col <width; col ++){int pixelvalue = result.getrgb(col、row); if(!colorindexmap.containskey(pixelvalue)){colorindexmap.put(pixelvalue、pixelvalue); }}} //今すぐピクセル値をスキャンしますcolorindexmap.keyset()。toarray(new Integer [0]);テストコードは次のとおりです。
public static void main(string [] args){file file = new file( "d://gloomyfish//bigmonkey.png"); file resultFile = new file( "d://gloomyfish//result.png"); try {bufferedimage image = imageio.read(file); bufferedimage result = removeblendpixels(mage、block_pixel_radius); Imageio.write(result、 "png"、resultFile); integer [] colors = extractcolors(result); System.out.println( "合計色:" + colors.length); } catch(ioexception e){e.printstacktrace(); }}注:主なキーは、処理する画像の正しいサイズを入力することです。この半径のサイズは、画像の実際のサイズに関連しており、アルゴリズムは、ゼロに等しいピクセルが見つかるまで、半径パラメーターに依存しないバージョンにさらに一歩最適化できます。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。