Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

OpenCV 없이 Java만으로 이미지를 그레이스케일로 변환하는 방법

개요

이미지 처리 작업에서 컬러 이미지를 그레이스케일(흑백)로 변환하는 일은 매우 기본적이면서도 자주 사용되는 기법입니다. 보통은 OpenCV 같은 전문 라이브러리를 활용하지만, Java 표준 라이브러리(java.awt, javax.imageio)만으로도 충분히 간단하게 구현할 수 있습니다. 이 글에서는 외부 라이브러리 없이 순수 Java 코드만으로 이미지를 그레이스케일로 변환하는 방법을 알아보겠습니다.

그레이스케일 변환의 원리

컬러 이미지는 각 픽셀이 빨강(Red), 초록(Green), 파랑(Blue) 세 가지 색상 값으로 이루어져 있습니다. 이를 그레이스케일로 바꾸려면 다음과 같은 단계를 거칩니다.

  • 각 픽셀의 R(빨강), G(초록), B(파랑) 값을 추출합니다.
  • 세 색상 값의 평균을 계산합니다.
  • 기존 RGB 값을 계산된 평균값으로 대체합니다.
  • 변경된 색상 값으로 새로운 픽셀 값을 생성합니다.
  • 새로운 값을 해당 픽셀에 다시 설정합니다.

R, G, B 값이 모두 동일해지면 사람 눈에는 회색조(명도 차이만 존재하는 흑백)로 보이게 되는 원리입니다.

예제 코드

아래 예제는 D:\Images\car.jpg 파일을 읽어 모든 픽셀을 순회하며 그레이스케일로 변환한 후, grey_image.jpg라는 이름으로 저장하는 전체 과정을 보여줍니다.

import java.io.File;
import java.io.IOException;
import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class Color2Grey {
    public static void main(String args[])throws IOException {
        // 이미지 파일 읽기
        File file= new File("D:\\Images\\car.jpg");
        BufferedImage img = ImageIO.read(file);
        for (int y = 0; y < img.getHeight(); y++) {
            for (int x = 0; x < img.getWidth(); x++) {
                // 픽셀 값 가져오기
                int pixel = img.getRGB(x,y);
                // 픽셀 값으로 Color 객체 생성
                Color color = new Color(pixel, true);
                // R, G, B 값 추출
                int red = color.getRed();
                int green = color.getGreen();
                int blue = color.getBlue();
                // R, G, B 값의 평균 계산
                int average = (red+green+blue)/3;
                // 새로운 Color 객체 생성
                color = new Color(average, average, average);
                // 변경된 색상을 이미지에 적용
                img.setRGB(x, y, color.getRGB());
            }
        }
        // 수정된 이미지 저장
        file = new File("D:\\Images\\grey_image.jpg");
        ImageIO.write(img, "jpg", file);
        System.out.println("Done...");
    }
}

코드 설명

1. 이미지 로드: ImageIO.read() 메서드로 지정된 경로의 이미지 파일을 BufferedImage 객체로 불러옵니다.

2. 픽셀 순회: 이중 for문을 사용해 이미지의 가로(x)와 세로(y) 방향으로 모든 픽셀을 하나씩 방문합니다.

3. 색상 분리 및 평균 계산: getRGB()로 얻은 정수형 픽셀 값을 Color 객체로 감싸면 개별 R, G, B 값을 손쉽게 꺼낼 수 있습니다. 세 값을 더해 3으로 나누면 해당 픽셀의 밝기 평균이 나옵니다.

4. 새 색상 적용 및 저장: 평균값으로 만든 새 Color 객체를 setRGB()로 다시 할당하고, 최종적으로 ImageIO.write()를 통해 JPG 형식으로 저장합니다.

입력 이미지

OpenCV 없이 Java만으로 이미지를 그레이스케일로 변환하는 방법

출력 결과

OpenCV 없이 Java만으로 이미지를 그레이스케일로 변환하는 방법

참고 사항

단순 산술 평균 방식은 구현이 간단하지만, 인간의 시각은 녹색에 더 민감하기 때문에 실제로는 가중치를 적용한 루마(luma) 공식(예: 0.299×R + 0.587×G + 0.114×B)을 사용하면 더 자연스러운 흑백 이미지를 얻을 수 있습니다. 또한 픽셀 단위 반복 작업이 많은 대용량 이미지라면 성능을 위해 getRGB()/setRGB() 대신 버퍼 배열 단위 처리를 고려하는 것도 좋습니다.