카테고리 없음

비트맵과 RGB

happy_life 2023. 8. 21. 16:04

이번 포스팅에서는 비트맵과 RGB에 대해 공부한 과정에 대해 포스팅하려고 합니다. 머신러닝 모델을 사용하던 중 32bit의 ARGB 비트맵을 RGB로 변환하는 코드를 공부하다, 호기심이 생겨 정리하는 포스팅입니다. 앱의 머신러닝 모델이 안드로이드의 비트맵 사진을 인식하기 위해서는 ARGB -> RGB 변환과정이 필요했기 때문입니다.

 

코드

float imageSTD = 255.0f;
FloatBuffer buffer = FloatBuffer.allocate(BATCH_SIZE * PIXEL_SIZE * INPUT_SIZE * INPUT_SIZE);
buffer.rewind();

int area = INPUT_SIZE * INPUT_SIZE;
int[] bitmapData = new int[area];

bitmap.getPixels(
                bitmapData,
                0,
                bitmap.getWidth(),
                0,
                0,
                bitmap.getWidth(),
                bitmap.getHeight()
        );
        
for (i in 0 until INPUT_SIZE - 1) {
    for (j in 0 until INPUT_SIZE - 1) {
        val idx = INPUT_SIZE * i + j
        val pixelValue = bitmapData[idx]

        // Extracting the color channels (ARGB) from the pixel value
        val alpha = (pixelValue shr 24 and 0xff) // Alpha channel
        val red = (pixelValue shr 16 and 0xff)   // Red channel
        val green = (pixelValue shr 8 and 0xff)  // Green channel
        val blue = (pixelValue and 0xff)         // Blue channel

        // Normalize and store the RGB values in the buffer
        buffer.put(idx, (red / imageSTD))        // Normalized Red
        buffer.put(idx + area, (green / imageSTD))  // Normalized Green
        buffer.put(idx + area * 2, (blue / imageSTD)) // Normalized Blue
    }
}

 

1. 비트맵의 정의

bitmap은 안드로이드에서 이미지를 표현하기 위해 사용하는 클래스입니다.  bitmap은 ARGB로 되어있습니다. ARGB는 32bit로 기존의 24bit인 RGB에 투명도의 8비트가 추가된 것입니다. 

 

따라서 pixelValue = 0xAARRGGBB의 경우 AA는 투명도, RR는 Red, GG는 green, BB는 blue의 각 8비트씩을 나타내는 것으로 볼 수 있습니다.

 

 

비트맵의 픽셀에서 각 요소 추출하기

예를 들어 0xFFAABBCC에서 RED값을 추출하려면 어떻게 해야하는지 보겠습니다.

 

11111111 10101010 10111011 11001100 를 shr 16 연산하여 아래와 같이 변환합니다. 

00000000 00000000 11111111 10101010 

 

이후 0xFF와 and연산을 합니다.

0xFF는 00000000 00000000 00000000 11111111입니다.  

 

 

따라서 

00000000 00000000 11111111 10101010 

&&&&&&&&&&&&&&&&&&&&&&&&&&&

00000000 00000000 00000000 11111111

 

연산을 하면 아래와 같은 결과를 가질 수 있습니다. 

00000000 00000000 00000000 10101010 

 

Alpha는 shr 24, RED는 shr 16, Green은 shr 8, BLUE는 바로 & 연산을 하면 각각의 요소를 추출할 수 있습니다.

 

 

 

2. RGB의 정의

빛의 삼원색인 "Red (빨강)", "Green (녹색)", 그리고 "Blue (파랑)"을 나타내는 약어입니다. 이것은 컴퓨터 그래픽과 이미지 처리 분야에서 가장 일반적으로 사용되는 색 공간 중 하나입니다. RGB는 각각 8bit로 0 ~ 255 으로 각각의 요소를 표현할 수 있습니다. 그리고 이를 16진법으로 나타내면 아래와 같습니다.

 

RGB

 

 

 

3. 픽셀과 해상도

픽셀은 디지털 이미지를 구성하는 최소 단위입니다. 이미지를 구성하는 작은점을 의미하는데, 위의 3x3 사각형에서 하나의 작은 사각형 단위를 의미합니다.

 

해상도는 디스플레이나 이미지의 선명도나 정확도를 나타낸느 것으로 가로 픽셀 수 x 세로 픽셀수로 표기됩니다. 위의 예시에서는 3x3이라고 할 수 있습니다.

 

 

 

4. bitmap과 RGB

위에서 공부한 개념들을 바탕으로 코드를 다시 이해해보겠습니다. 

1. inputsize x inputsize는 해상도와 픽셀을 의미합니다. (640 x 640) 

2. bitmapData[idx]에 들어있는 각 픽셀의 ARGB 데이터를 받아옵니다.

3. shr 연산 등을 사용해 R, G, B 각 요소를 꺼냅니다.

4. 버퍼의 알맞은 위치에 R, G, B를 정규화하여 저장합니다.

 

 

 

참고

https://www.youtube.com/watch?v=2mWc3YqlM7c