이 기사에서는 색상 이미지에서 기본 색상을 얻기 위해 Java의 예제 코드를 설명합니다. 다음과 같이 참조에 대해 공유하십시오.
1 : 기본 아이디어
RGB 색상 공간의 컬러 이미지의 경우 여러 번 프로그램을 통해 이미지의 여러 주요 색상을 얻고 싶습니다. 그러나 일반적인 이미지의 경우 컬러 접합에서 픽셀 혼합이 달성됩니다. 따라서 이미지의 픽셀 값을 직접 스캔하면 수백 가지의 다른 색상 값이 발생할 수 있습니다. 실제로 이미지에는 3 ~ 4 개의 주요 색상 만 가질 수 있습니다. 혼합 색상을 제거 하고이 3-4의 주요 색상을 정확하게 추출하는 방법 일반 이미지의 특성에 따라 이미지는 동일한 색상의 경계에서 다른 색상 값을 혼합하지 않으면 이미지의 가장자리 특성 중 하나로 간주 될 수 있습니다. 따라서, 이들 혼합 픽셀의 추출물은 간단한 에지 그라디언트 알고리즘에 따라 출력 픽셀 값 배열을 얻은 다음 각 픽셀 값을 스캔하여 지정된 반경 매개 변수 r 주위의 픽셀을 찾고 중앙 픽셀에 가장 가까운 픽셀 포인트의 값이 중심 값으로 사용됩니다. 스캔이 완료되면 픽셀 어레이가 출력 될 수 있으며, 배열을 선형으로 스캔하여 사진의 기본 색상 RGB 값을 얻을 수 있습니다.
두 가지 : 구현 단계
1. 이미지 배열을 컬러 이미지를 그레이 스케일로 입력하십시오.
2. 그레이 스케일 이미지의 경우 이미지 그라디언트를 계산하고 여기에서 Sobol 연산자를 사용하십시오.
3. 0이 아닌 각각의 픽셀 포인트에 대해 반경 r 범위 내에서 스캔하고 가장 가까운 원래 픽셀 값이 0을 찾으십시오.
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 [너비 * 높이]; getrgb (이미지, 0, 0, 너비, 높이, 픽셀); // 프로세싱 생성 resultBufferEdImage resultImg = createCompatibledStimage (image, null); setrgb (resultimg, 0, 0, 너비, 높이, 픽셀); // 프로세싱 생성 resultBufferEdImage resultImg = createCompatibledStimage (image, null); setrgb (resultimg, 0, 0, 너비, 높이, 픽셀); // GrayScale 및 Gradient Byte [] GrayData = GetGrayData (픽셀, 너비, 높이); 바이트 [] binaryData = getGrident (그레이 다타, 너비, 높이); 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) {// 반경 스캔 작동 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> = 높이) {계속; } for (int subcol = -raidus; subcol <= raidus; subcol ++) {nc = col+subcol; if (nc <0 || nc> = 너비) {계속; } index2 = nr * width + nc; int value = (binaryData [index2] & 0xff); if (value == 0) {int 거리 = DistanceColor (image.getrgb (nc, nr), image.getrgb (col, row)); if (거리 <mindis) {mindis = 거리; minrow = nr; mincol = nc; }}}} resultimg.setrgb (col, row, image.getrgb (mincol, minrow)); }}} return resultimg; } public static int distancecolor (int rgb, int rgb2) {// 색상 One 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 bd 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 grey = (int) (0.299 * tr + 0.587 * tg + 0.114 * tb); 아웃 픽셀 [index] = (바이트) (그레이 & 0xff); }} return outpixels; } public static bd 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 == 높이 -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> = 높이) {nrow = 0; } if (ncol <0 || ncol> = 너비) {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); outpixels [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}}; 공개 정적 최종 int block_pixel_radius = 5; 그라디언트 획득은 Sobol Operator를 사용합니다. 메인 색상을 얻기 위해 처리 후 BufferedImage 객체를 스캔하는 코드는 다음과 같습니다.
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); }}} // 이제 픽셀 값을 스캔 // return result system.out.println ( "색상 숫자 =" + colorIndexMap.size ()); return colorIndexMap.keyset (). ToArray (New Integer [0]); 테스트 코드는 다음과 같습니다.
public static void main (String [] args) {file file = new File ( "d : //gloomyfish//bigmonkey.png"); file resultfile = 새 파일 ( "d : //gloomyfish//result.png"); {bufferedImage image = imageio.read (file); BufferedImage result = removeBlendPixels (image, block_pixel_radius); imageio.write (result, "png", resultfile); 정수 [] 색상 = ExtractColors (결과); System.out.println ( "총 색상 :" + colors.length); } catch (ioexception e) {e.printstacktrace (); }}참고 : 주요 키는 처리 할 이미지의 올바른 크기를 입력하는 것입니다. 이 반경 크기는 이미지의 실제 크기와 관련이 있으며, 알고리즘은 픽셀이 0과 같은 픽셀을 찾을 때까지 반경 매개 변수에 의존하지 않는 버전으로 한 단계 더 최적화 될 수 있습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.