개발자수행중
June 15, 2023, 4:45am
1
1280 * 960 Size의 Image가 있다고 가정하며
해당 이미지는 IntPtr 자료형이라고도 가정합니다.
이 경우 해당 Image의 평균 밝기 값을 계산하기 위해 아래와 같이 구현하였습니다.
double fResult = -1.0;
unsafe
{
byte* ptr = (byte*)Img;
int i;
int dataCount = width * height;
fResult = 0;
for (i = 0; i < dataCount; i++)
{
fResult += ptr[i];
}
fResult = fResult / (double)dataCount;
}
return fResult;
다만, 전체 영역의 밝기 값이 아니라 ROI로 지정된 영역만 평균 밝기 값을 획득하고 싶습니다.
질문의 요지를 이해를 돕기 위해 아래 이미지를 봐주세요.
이미지의 원본 크기는 1280 * 960이지만 Yellow 영역 부분의 밝기 값을 전부 더하여 평균을 내고 싶습니다. 어떻게 접근해야 할지 답변 부탁드립니다.
1 Like
스노우맨
June 15, 2023, 5:17am
2
for (int i=y; i <= y+height; i++)
{
for (int j=x; j <= x+width; j++)
{
int pos = i * 1280 + j;
fResult += ptr[pos];
}
}
이렇게 계산하면 되지않을까요
1 Like
al6uiz
June 15, 2023, 5:35am
3
비트맵 데이터의 픽셀 포맷에 따라 로직이 달라질 것으로 보입니다.
적어주신 코드를 보면 픽셀 당 1 바이트를 가지는 그레이스케일 포맷인 것 같네요.
또한 비트맵 데이터의 한 세로 픽셀 당 가로 데이터의 길이인 Stride라는 것을 고려해야 하는데요,
비트맵 데이터의 효율적인 처리를 위해 {픽셀 포맷 * 이미지 가로 픽셀} 값이 보통 4의 배수로 정렬되어 dataCount에 해당하는 값이 width * height이 아닐 경우가 있습니다.
(보통 C#의 System.Drawing.Bitmap.LockBits()등의 함수를 호출하면 PixelFormat, Stride 값을 속성으로 얻을 수 있습니다.)
참고: Image Stride - Win32 apps | Microsoft Learn
@스노우맨 님의 코드와 유사하지만 Stride를 고려한 코드입니다.
double fResult = 0;
unsafe
{
byte* ptr = (byte*)Img;
int x, y;
int dataCount = width * height;
var stride = imgWidth;
for (y = 0; y < height; y++)
{
ptr = (top + y) * stride + left;
for (x = 0; x < width; x++)
{
fResult += ptr++;
}
}
fResult = fResult / dataCount;
}
return fResult;
2 Likes
개발자수행중
June 15, 2023, 5:55am
4
친절한 답변 감사합니다. stride는 단순 image의 width 값인가요 ?
1 Like
스노우맨
June 15, 2023, 6:00am
5
일반적으로 stride = 픽셀당 바이트수 * width 입니다.
일정 배수를 맞추려고 뒤에 +알파 해야하는 경우도 있습니다.
1 Like
al6uiz
June 15, 2023, 6:09am
6
올려주신 코드를 보면 한 픽셀이 1바이트인 그레이스케일 픽셀 포맷을 사용하시는 것 같아서 예제를 단순히 원본 이미지의 Width로 적어놓은 것이고요, 실제로는 조금 더 복잡합니다.
예를 들어 픽셀 포맷이 1바이트이고 가로 크기가 1280이라면 1280 * 1은 4의 배수이기 때문에 Stride는 1280이 되지만, 가로 크기가 142라면 Stride는 142에 Padding 2바이트를 추가해서 4의 배수인 144가 됩니다.
그리고 RGB(24bits) 또는 RGBA(32bits)여부에 따라서도 달라지고 라이브러리에 따라 RBG를 3바이트 또는 4바이트로 달리 처리할 수도 있고 Stride에 Padding을 고려하지 않고 비트맵 데이터를 생성할 수도 있습니다.
실무에서는 이러한 고려 사항들을 인지하고 직접 확인해 본 뒤 로직을 작성해야 합니다.
1 Like