顯示具有 黃聖峰 標籤的文章。 顯示所有文章
顯示具有 黃聖峰 標籤的文章。 顯示所有文章

12/22/2006

膚色切割器


膚色分割通常是做人臉辦識最重要的一件事,

要是沒先把膚色給分類出來並加以定位人臉的的位置, 
則會影響接下來的辨識結果.


切割膚色有很多的分法,這個切割器我是使用ycbcr的方法來做為偵察.
為什麼使用ycbcr呢:

因為RGB的色彩空間很容易受到光源的影響而有明顯的變化,

而使在設定顏色的分割值,會有很大的大的誤差.
又因為ycbcr有良好的亮度和色度分離的特特(彩度)所以我就使用它.

在此Y 代表亮度,Cb和CR都代表色度(彩度) 轉換公式如下

但在matlab你不用建立上式,只要打rgb2ycbcr('檔案')轉換就可以了


%----程式碼-----

clear all
close all
clc
a=imread('nomo.jpg'); % 輸入影像

b=rgb2ycbcr(a); % 轉換成ycbcr
cb=b(:,:,2);
cr=b(:,:,3);

cb(cb<=125)=255; % cb的判斷式,是膚色為白色
cb(cb~=255)=0;
figure(1);imshow(cb)

cr(cr>=137)=255; % cr的判斷式,是膚色為白色
cr(cr~=255)=0;
figure(2);imshow(cr)

rr=and(cr,cb); % 找出二者都是白的
rt(:,:,1)=double(rr).*double(a(:,:,1));
rt(:,:,2)=double(rr).*double(a(:,:,2));
rt(:,:,3)=double(rr).*double(a(:,:,3));
figure(3);imshow(uint8(rt))


%--------------結果----------
原影像圖,如下

分割後的cb影像,如下

分割後的cr影像,如下

只秀出膚色圖


以上就是建立膚色切割器的基礎公式
由上方的圖可知,這些影像還一些小雜點,在這我用形態學中的Opening operation來消除雜點
雜訊去除

形態學
Opening(斷開)運算:
opening運算是先被侵蝕後再膨脹,通常是用來平滑影像輪廓,截斷窄的細頸,消除細的突支,
其原理如下:
(一)膨脹:將物體的邊界往外膨脹若干像素的方法。 如下圖:

(二)侵蝕:與膨脹相反的動作,這是一種從物體的邊界上,將物體往內收縮若干像素。
如下圖:

斷開圖如下

標記法:
兩像素間關係有下述兩種性質:
(一)像素的近鄰(neighbors):
在座標(x,y)處的像素P有水平和垂直方向的近鄰,其座標為
(x-1,y),(x+1,y),(x,y+1),(x,y-1),
這樣一組像素稱P點的4-近鄰(4-nieghbors)。

P的四個對角近鄰的座標為(x-1,y+1),(x+1,y+1),(x-1,y-1),(x+1,y-1),
這些點與4-近鄰在一起,稱為P的8-近鄰(8-neighbors)。

(二)連通性(Connectivity):
像素間的連通性是用於確定影像中物體邊界和區域組成成分的重要概念。
要判斷兩個像素是否連通,必須要確定它們是否在某種意義中相鄰(如它們是否為4-近鄰),
並且它們的灰度值是否滿足特定的相似準則,(如灰度值是否相同)。
在此我們用V來定義連通性的灰階集合,並介紹二種類型的連通:
(a)4-連通:
若某一像素Q 位於4-近鄰( P)中,且Q和P的像素值位於所定的灰度值(V)中,則稱4-連通。
(b)8-連通:
若某一像素Q位於8-近鄰( P)中,且Q和P的像素值位於所定的灰度值(V)中,則稱8-連通。

(三)標記法原理:
標記法是使用在二值化影像,白色為255,黑色為0,p表掃描過程中之像素值;
先由左而右,再由上而下掃描影像,在此只考慮4-連通分量。
當掃描到為0的時則移動到下一掃描位置,當掃描到p為255的,並根據其連通性檢查p點的左方和上方,
如果它們均為0的為話,給p一個新的標記值,如果這二個近鄰中只有一個為255,
則把它的標記給予p,如果它們都是255且標記相同,則把這個標記給予p。
如果它們都是255但標記不同,則把其中一個標記給予p,並標明這兩個標記是等價的。
掃描結束後所有值為255的點都被標記過了,但有些標記是可能是等價的,
所以再對影像作第二次掃描,將所有被記錄為等價的標記值改成相同的標記。

新增加的程式碼

se=strel('disk',2);%用open過濾膚色圖像
bw= imopen(rr,se);
figure(4);imshow(bw)

%用open過濾後的圖,再用標記法來找出最大區塊
l=bwlabel(bw,8); % 標記法

stats=regionprops(l,'Area'); % 找出相同的並統計
allArea=[stats.Area];
tt=max(allArea); % 找出最大的區塊
idx=find(allArea==tt);
bw2=ismember(l,idx);
figure(5);imshow(bw2)%過濾後的人臉圖像
%----------------------------------------------------
GUIDE
首先把一張rgb的照片轉成ycbcr(y代表亮度,cb代表色度(blueness),cr也代表色度(redness))
然後我們可以使用slider來調整y cb cr的範圍,使它只出現膚色的範圍
即可達到膚色分割了

膚色切割器檔案下載

11/28/2006

小程式 月曆產生器


把程式加入介面


GUIDE程式說明

首先在command window下打guide就會出現下圖


接下來選Blank GUI(Default),就會開啟新的window,如下圖


接下來你會看到左邊有很多控制物件,
你只要以滑鼠點選其中一項
並把它拖到你想要的位置就可以.

月曆這個程式我有用到[push button]二個(run 和run)、
九個[text](如萬年曆、月、年和藍底的框都是),
而其它的空白框則都是[edit](可以key in數字的)。
如下圖
(小格子是中文字,因為我7版的不能用,所以我就用6.5版的
,在此要注意,應該會有些指令在6.5不能用)。



而要是想更改其顏色,字體等…則在其物件點擊二下則會出現下圖(這是以紅色的run為例子),
或是mark其物件,選View,再選Property Inspector也可以


當你選擇好你要用的物件,即可存檔。此時你會存成二個檔
一個叫 xxx.fig的檔,另一個是xxx.m的檔。接下來則是程式編輯的部份了,
點選View,再選M-file Editor即可開始編輯程式。
當你一開啟M-file你就會看到密密麻麻的字,但在這個程式會用到的只有幾個而已。

大部份我們都是在function 物件名稱_callback(hObject, eventdata, handles)
下編輯其程式,如下圖:

這個程式的[edit物件名稱]空白處的程式碼為
function edit物件名稱_Callback(hObject, eventdata, handles)
% hObject handle to edit8 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
newstrval=get(hObject,'string'); % 截取輸入的字串
newval=str2double(newstrval); % 變成數字
handles.edit物件名稱=newval; % 存儲起來
guidata(hObject,handles);
% Hints: get(hObject,'String') returns contents of edit8 as text
% str2double(get(hObject,'String')) returns contents of edit8 as a double
以下為pushbutton的圖

這個程式的[pushbutton物件名稱]的程式碼為

Function pushbutton物件名稱_Callback(hObject, eventdata, handles)

% hObject handle to pushbutton3 (see GCBO)

% eventdata reserved - to be defined in a future version of MATLAB

% handles structure with handles and user data (see GUIDATA)

Y=handles.edit6; % 截取年的值
M=handles.edit7; %
截取月的值
K=handles.edit8; % 截取日的值

% 以下為判斷你輸入的日子是星期幾

if rem(Y,100)==0 & rem(Y,400)==0 | rem(Y,4)==0
d1=[31 29 31 30 31 30 31 31 30 31 30 31];
else
d1=[31 28 31 30 31 30 31 31 30 31 30 31];
end
s=Y-1;
c=d1(1:(M-1));
c1=sum(c)+K;
ss=s+fix(s/4)-fix(s/100)+fix(s/400)+c1;
dd=rem(ss,7)+1;
di=['日','一','二','三','四','五','六'];
ggo=sprintf('你查詢的%d年%d月%d日是星期%s',Y,M,K,di(dd));
set(handles.text12,'string',ggo); % 把它show出來在藍色框框中如下圖



另一個[pushbutton物件名稱]的程式碼為
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Y=handles.edit9; % 讀取年的值
M=handles.edit10; % 讀取用的值
ans=[ ];
if rem(Y,100)==0 & rem(Y,400)==0 | rem(Y,4)==0
d1=[31 29 31 30 31 30 31 31 30 31 30 31];
else
d1=[31 28 31 30 31 30 31 31 30 31 30 31];
end
s=Y-1;
c=d1(1:(M-1));

% 以下為建月曆的運算式
for k=1:d1(M)
c1=sum(c)+k;
ss=s+fix(s/4)-fix(s/100)+fix(s/400)+c1;
ans(k)=rem(ss,7);
end
ans(ans==0)=7;
pp=ans(1);
ans1=[ ];

k1=0;
for n=1:6;
for m1=pp:7
ans1(n,m1)=k1;
k1=k1+1;
end
pp=1;
end
ans1(ans1>d1(M))=0; % 結果
% 以下就是把所出來的值給代入小格子
(這個東東,還可以修改)

set(handles.e1,'string','日');
set(handles.e2,'string','
一');
set(handles.e3,'string','二');
set(handles.e4,'string','
三');
set(handles.e5,'string','
四');
set(handles.e6,'string','五');
set(handles.e7,'string','六');

set(handles.e8,'string',num2str(ans1(1,1)));
set(handles.e9,'string',num2str(ans1(1,2)));
set(handles.e10,'string',num2str(ans1(1,3)));
set(handles.e11,'string',num2str(ans1(1,4)));
set(handles.e12,'string',num2str(ans1(1,5)));
set(handles.e13,'string',num2str(ans1(1,6)));
set(handles.e14,'string',num2str(ans1(1,7)));

set(handles.e15,'string',num2str(ans1(2,1)));
set(handles.e16,'string',num2str(ans1(2,2)));
set(handles.e17,'string',num2str(ans1(2,3)));
set(handles.e18,'string',num2str(ans1(2,4)));
set(handles.e19,'string',num2str(ans1(2,5)));
set(handles.e20,'string',num2str(ans1(2,6)));
set(handles.e21,'string',num2str(ans1(2,7)));

set(handles.e22,'string',num2str(ans1(3,1)));
set(handles.e23,'string',num2str(ans1(3,2)));
set(handles.e24,'string',num2str(ans1(3,3)));
set(handles.e25,'string',num2str(ans1(3,4)));
set(handles.e26,'string',num2str(ans1(3,5)));
set(handles.e27,'string',num2str(ans1(3,6)));
set(handles.e28,'string',num2str(ans1(3,7)));

set(handles.e29,'string',num2str(ans1(4,1)));
set(handles.e30,'string',num2str(ans1(4,2)));
set(handles.e31,'string',num2str(ans1(4,3)));
set(handles.e32,'string',num2str(ans1(4,4)));
set(handles.e33,'string',num2str(ans1(4,5)));
set(handles.e34,'string',num2str(ans1(4,6)));
set(handles.e35,'string',num2str(ans1(4,7)));

set(handles.e36,'string',num2str(ans1(5,1)));
set(handles.e37,'string',num2str(ans1(5,2)));
set(handles.e38,'string',num2str(ans1(5,3)));
set(handles.e39,'string',num2str(ans1(5,4)));
set(handles.e40,'string',num2str(ans1(5,5)));
set(handles.e41,'string',num2str(ans1(5,6)));
set(handles.e42,'string',num2str(ans1(5,7)));

set(handles.e43,'string',num2str(ans1(6,1)));
set(handles.e44,'string',num2str(ans1(6,2)));
set(handles.e45,'string',num2str(ans1(6,3)));
set(handles.e46,'string',num2str(ans1(6,4)));
set(handles.e47,'string',num2str(ans1(6,5)));
set(handles.e48,'string',num2str(ans1(6,6)));
set(handles.e49,'string',num2str(ans1(6,7)));

下面為顯示結果圖

等程式都key in完,就可以按run,即可執行程式
月曆產生器檔案下載

10/03/2006

problem#02黃聖峰

%------------------------程式碼----------------------------------%
close all;
clc;
%-----------------------第一題 ----------------------------------%
%----------這是個温度換算和找出超過攝氏38度的程式------------------%
F=[98 100 102 104 98.4 98.2 98.5 101 102 99.5]; % Fahrenheit %
question_1_Centigrade=(F-32)*5/9 % Fahrenheit to Centigrade %
question_1_D=(question_1_Centigrade > 38) % 找出大於38度的denote "1"and "0" for the normal %
%-----------------------------------------------------------------%


%-------------------------第二題-----------------------------------%
%-----------------這是個matrices的判斷式----------------------------- %
A=[-10 8 6 4 -5 20];
B=[2 8 5 10 -6 3];
question_2_D_1=(A>B) % 找出A>B %
question_2_D_2=(A>5) % 找出A>5 %
question_2_D_3=(A+B) % A+B %
%------------------------------------------------------------------%


%----------------------------第三題--------------------------------%
%--------------------------這是個矩陣運算的程式------------------------ %
x=[10 20 30];
y=[1 4 6];
question_3_a=3*x+y
question_3_b=5*y./x
uestion_3_b1=5*y/x
question_3_c=4*x*2.*y
question_3_d=sind(x).*cosd(y)
question_3_e=5*x.*sind(2*y)

%在這一題要注意的是點的應用;而B=5y/x這一個題目很特別,因為有"有點b=5*y./x"和"沒點b1=5*y/x"的答案會有差異%
%------------------------------------------------------------------------%


%-----------------------------第四題--------------------------------------%
%----------------------------這是個電阻串並聯的換算------------------------%
R=[10 30 200 400]; %四種電阻%
R1=sum(R) %電阻串聯為全部的電阻值相加%
R2=1/(sum(1./R)) %利用並聯電阻公式1/R = 1/R1 + 1/R2求出並聯時的電阻值%
%------------------------------------------------------------------------%


%-------------------------第五題----------------------------------------%
%-----------------------------這是個矩陣重新排列的程式-------------------%
a=1:24;
question_5_b=reshape(a,3,8) %重新組成的 3x8 矩陣%
question_5_c=reshape(a,6,4) %重新組成的 6x4 矩陣%
question_5_d=reshape(a,2,12) %重新組成的 2x12 矩陣%
%------------------------------------------------------------------------%

執行結果
question_1_Centigrade =
36.6667 37.7778 38.8889 40.0000 36.8889 36.7778 36.9444 38.3333 38.8889 37.5000

question_1_D = 0 0 1 1 0 0 0 1 1 0

question_2_D_1 = 0 0 1 0 1 1
question_2_D_2 = 0 1 1 0 0 1
question_2_D_3 = -8 16 11 14 -11 23

question_3_a = 31 64 96
question_3_b = 0.5000 1.0000 1.0000
question_3_b1 = 0.9643
question_3_c = 80 640 1440
question_3_d = 0.1736 0.3412 0.4973
question_3_e = 1.7450 13.9173 31.1868

question_4_R1 = 640
question_4_R2 = 7.1006


question_5_b =
1 4 7 10 13 16 19 22
2 5 8 11 14 17 20 23
3 6 9 12 15 18 21 24

question_5_c =
1 7 13 19
2 8 14 20
3 9 15 21
4 10 16 22
5 11 17 23
6 12 18 24

question_5_d =
1 3 5 7 9 11 13 15 17 19 21 23
2 4 6 8 10 12 14 16 18 20 22 24

9/30/2006

Problem#01黃聖峰

加選後補交的作業
%---------------程式碼--------------------------%
close all;
clc;
%---------------第一題--------------------------%
F=200; % pull force %
V=20/60; % m/min 變 m/sec %
J=0.101972; % 1J=0.101972 %

question_1_Power=F*V/J % 功率KW %
%-----------------------------------------------%

%---------------第二題---------------------------%
R1=1; % 電阻1 %
R2=20; % 電阻2 %
R3=200; % 電阻3 %
V=110; % 電壓(V) %

question_2_I=V/(R1+R2+R3) % 電流(A) %

question_2_Power=V*I % 功率(W) %
%-------------------------------------------------%

%--------------第三題------------------------------&
A=650; % 第一個邊長 %
B=428; % 第二個邊長 %
C=282; % 第三個邊長 %
s=(A+B+C)/2;

question_3_area=(s*(s-A)*(s-B)*(s-C))^(1/2) % 用Heron公式求三角形面積 %
%---------------------------------------------------%

%--------------第四題-------------------------------%
Lheat=25000; % heat from light and equipment %
Wheat=52000; % heat through wall and cell %
Fheat=84300; % heat through aerations %

question_4_N=(Wheat+Fheat-Lheat)/600 % how many hogs this house can raise %
%----------------------------------------------------%

%---------------第五題--------------------------------%
L=4; % 堰口寬度L為4呎 %
H=0.9; % 堰口溢流水頭高度H為0.9呎 %
question_5_Q=3.33*(L-0.2*H)^(3/2) % 堰口每秒流量 %
%----------------------------------------------------%


執行結果
question_1_Power =
653.7742 % 功率為653.7742 kw %

question_2_I =
0.4977 % 電流為0.4977A %

question_2_Power =
54.7511 % 功率為54.7511 w %

question_3_area =
4.5233e+004 % 面積為4.5233e+004平方公分 %

question_4_N =
185.5000 % 185頭豬最適合 %

question_5_Q =
24.8622 %堰口每秒流量為24.8622立方呎/秒
>>