在此我也來試試看用電腦處裡能不能到達相同效果
後來發現RGB轉成 HSV 格式後 利用H的色調做判別就能達成了
轉換公式 :
排序 | 色相區域 | 公式 |
---|---|---|
紅色-黃色 | ||
黃色-綠色 | ||
綠色-青色 | ||
青色-藍色 | ||
藍色-品紅色 | ||
品紅色-紅色 |
程式碼:
#include
<stdio.h>
#include
<cv.h>
#include
<highgui.h>
#include
<iostream>
using
namespace
std ;
void
RGBtoHSV( float r,
float
g,
float
b,
int
*h,
float
*s,
float
*v
)
{
//轉換成
0 ~ 1 之間
r = r
/ 255 ;
g
= g / 255 ;
b
= b / 255 ;
// RGB 轉 HSV 公式
if
(r
>= g && g>=
b)
*h
= 60*(g-b)/(r-b);
if
(g
> r && r
>= b)
*h
= 60*(2-((r-b)/(g-b)));
if
(g
>= b && b
> r)
*h
= 60*(2+ ((b-r)/(g-r)));
if
(b
>g && g>r)
*h
= 60*(4 - (g-r)/(b-r));
if
(b>r
&& r>=g)
*h
= 60*(4 + (r-g)/(b-g));
if
(r>=b
&& b>g)
*h
= 60*(6-(b-g)/(r-g));
if(
*h
< 0 )
*h
+= 360;
else
*h = *h%360
;
}
void
RGB_HSV(IplImage * temp)
{
//創造和src一樣的IplImage資料結構
IplImage
* rgb = cvCreateImage( cvGetSize(temp), 8, 3
);
cvCopy(temp,rgb);
//創造和src一樣的IplImage資料結構
IplImage
* hsv = cvCreateImage( cvGetSize(rgb), 8, 3 );
cvCopy(temp,hsv);
int
H=cvGetDimSize(rgb,0);//讀取矩陣高度
int
W=cvGetDimSize(rgb,1);//讀取矩陣寬度
int
sum = 0;
for(int
y = 0 ; y < H ; y++)
for(int
x = 0 ; x < W; x++ )
{
int
H = 0;
float
S = 0;
float
V = 0;//讀取圖片
hsv 值
float
R ,G ,B ;
float
GY;
R =
cvGet2D(rgb,y,x).val[2] ;
G = cvGet2D(rgb,y,x).val[1] ;
B =
cvGet2D(rgb,y,x).val[0] ;
GY = (R+G+B)/3 ;//RGB
RGBtoHSV(R,G,B,&H,&S,&V);//轉換
if(
!(H > 180 && H < 230))//不是藍轉成灰
cvSet2D(hsv,y,x,CV_RGB(GY,GY,GY));//寫入
}
cvNamedWindow( "Source-RGB",
0 );
cvShowImage( "Source-RGB",
rgb );
cvNamedWindow( "Source-HSV",
0 );
cvShowImage( "Source-HSV",
hsv );
}
int
main( int argc,
char
**argv )
{
IplImage*
img = cvLoadImage("people.jpg",1);
RGB_HSV(img);
int
h = 0;
float
s = 0;
float
v = 0;
cvWaitKey(0);
return 0;
}