본문 바로가기
C#

[C#] 이미지를 오로지 R , G , B 만으로 표현하기 (색 분류)

by 슈퍼닷 2017. 12. 28.
반응형

R , G , B는 각각 빨강 , 초록 , 파랑 이다. ( 빛의 삼원색 )

B를 X축 G를 Y축 R 을 Z축 으로 정하자 -> (B , G , R )  = (X , Y , Z) 

B의 좌표는 (255,0,0) G의 좌표는 (0,255,0) R의 좌표는 (0,0,255) 라 하자.


[색 좌표]


우리는 우리가 얻은 색깔을 "어떤 색상에 가까운가" 를 기준으로 분류를 할수 있을것이다. 

[제대로된 처리를 못하는 중간값이 생길수는 있다. EX) 검은색(0,0,0)].

어떤 색상에 가까운지는 Color와 R,G,B간의 "거리" 를 비교하여 알수 있을것이다.

거리는 두점사이의 거리 공식을 사용하면 되겠다.  distance = sqrt {  (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2 }

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
        public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);

using System.Drawing; 


struct Vector3

{

public int x,y,z; 

public Vector3(int px, int py, int pz)

{

x = px; y = py; z = pz;

}

}

private void MakeImageToRGB(ref orginal){

Vector3 [] color = { new Vector3(255,0,0) , new Vector3(0,255,0) , new Vector3(0,0,255)}; // B , G , R

const int COLOR_COUNT = 3;

int height = orignal.Height;

int width = original.Width;

int distance , pos , index = 0;

int min = 255*255*3;

Rectangle rect = new Rectangle(0,0,width,height);

BitmapData orgdata = original.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

int stride = orgdata.Stride;

int size = stride * height;

byte[] rgbValues = new byte[size];

System.Runtime.InteropServices.Marshal.Copy(orgdata.Scan0, rgbValues, 0, size);


for(int y = 0; y < height ; y++)

{

for(int x = 0; x< width ; x++)

{

pos = x*3 + y*stride;

for(int i = 0; i < COLOR_COUNT ; i++)

{

distance = Pow(rgbValues[pos] - color[i].x) + Pow(rgbValues[pos+1] - color[i].y) + Pow(rgbValues[pos+2] -color[i].z);

if ( distance < min)

{

min = distance; index = i;

}

rgbValues[pos] = color[index].x ; 

rgbValues[pos+1] = color[index].y; 

rgbValues[pos+2] = color[index].z;

min = 255*255*3;

}

}

System.Runtime.InteropServices.Marshal.Copy(rgbValues,orgdata.Scan0, 0, size);

original.UnlockBits(orgdata);

}

private int Pow(int a)   // 제곱 함수 

{

return a*a;

}



 

흰색이나 검은색을 추가하고 싶으면 color 배열에 (255,255,255 ) 와 (0,0,0) 을 추가하고 COLOR_COUNT 를 늘려주면 되겠다.

반응형

'C#' 카테고리의 다른 글

[C#] 실행시간 측정 Stopwatch  (3) 2018.08.13
[C#] HSV에서 Hue 의 거리  (0) 2018.07.09
[C#] 픽셀서치 PixelSearch 2  (0) 2017.09.16
[C#] 픽셀서치 PixelSearch  (4) 2017.08.25
[C#] Xamarin with CocosSharp 공튀기기  (0) 2017.03.04

댓글