تشخیص فونم ها(لب خوانی) با SVM در متلب

شبیه سازی با متلب

میخواهیم در این پست آموزشی تشخیص واج ها یا فونم ها را با متلب انجام دهیم. برای این منظور داده ها را برای هم آوا(واج یا فونم) 4بار تهیه و ذخیره می کنیم. این تعداد هر چه بیشتر باشد الگوریتم دقیق تر عمل می کند. چون در اینجا داده های ما کم هست از الگوریتم SVM که خروجی بهتری را می دهد استفاده می کنیم.

در این آزمایش برای هر آوا 4بار با اشخاص مختلف و با گرفتن تصویر ویدویی از لب خوانی آنها دیتای اولیه را تهیه می کنیم. بعد نیاز هست تا آنها را با عدد مشخص کنیم و به این صورت که پشت سر هم باشند. یعنی اگر 10فونم داریم. باید 40ویدیو باشد که اولی 1 و آخری 40 نام گذاری شده است

بهتر هست سریعتر به همراه برنامه متلب آن آموزش متلب را آغاز کنیم. در توضیحات زیر منظور از عکس همین ویدیو های تهیه شدست:

قسمت ابتدایی برای پاک کردن صفحه، حافظه و اشکال

clc

clear all

close all

[n p]=uigetfile;

گرفتن مسیر عکسها

numImg=input(‘Enter The Image Numbers’);

گرفتن تعداد عکسها

TraImg=input(‘Enter The Image Number for each class’);

گرفتن اینکه هر کلاس چند عکس را شامل می­باشد

imgbank=cell(numImg,1);

تعریف بانک تصویر

T1=cell(numImg,1);

T2=cell(numImg,1);

متغیرهای گرفتن طول و عرض دهان

for ii=1:numImg

خواندن عکسها و ذخیره در متغیر خاص

برای هر عکس

a=num2str(ii);

اعداد عکسهارا به متن تبدیل کردن

n=strcat(a,’.avi’);

مخلوط کردن عکس با پسوند avi

img=read(mmreader([p n]));

خواندن عکس با گرفتن مسیر و نام عکس

imgbank{ii,1}=(img);

ذخیره عکس در بانک تصاویر

[rr cc zz ff]=size(img);

imgg=cell(ff,1);

ایجاد متغیری برای نگهداری فریمها

خواندن و استخراج تصویر لب بر اساس پیکسلها

for jj=1:ff

برای هر فریم

imgh=imgbank{ii,1}(:,:,:,jj);

خواندن از بانک تصاویر

imgbw1=(imgh(:,:,1)>130 & imgh(:,:,1)<210 & imgh(:,:,2)>40 & imgh(:,:,2)<90 & imgh(:,:,3)>30 & imgh(:,:,3)<90);

پیکسهای خاصی را که مربوط به لب است جدا کردن

imgbw2=(imgh(:,:,1)>100 & imgh(:,:,1)<150 & imgh(:,:,2)>45 & imgh(:,:,2)<75 & imgh(:,:,3)>45 & imgh(:,:,3)<75);

پیکسهای خاصی را که مربوط به اطراف لب است جدا کردن

imgt=imgbw1+imgbw2;

ترکیب آنها

استخراج مسک برای حذف جاهای اضافی

[rr cc]=size(imgt);

b=zeros(rr,cc);

for iii=31:rr-30

for jjj=76:cc-75

b(iii,jjj)=sum(sum(imgt(iii-30:iii+30,jjj-75:jjj+75)));

با بلوکی به بزرگ 60 در 150 دنبال جایی هستیم که تصویر بیشترین 1 را دارد که موقعیت همان لب است

end

end

[aa bb]=find(b==max(max(b)));

بیشترین یک را پیدا کردن

c=zeros(size(b));

g1=min(aa);

g2=max(aa);

g3=min(bb);

g4=max(bb);

if g1<41

اگر minاز 41 کمتر باشد منظورکنار تصویر لب داشته باشیم

g1=41;

مینیمم را 41 بگیر

end

if g2>rr-40

مانند بالا

g2=rr-40;

end

if g3<121

g3=121;

end

if g4>cc-120

g4=cc-120;

end

c(g1-40:g2+40,g3-120:g4+120)=1;

imgt1=imgt.*c(1:rr,1:cc);

مسک را در تصویر ضرب و لب را استخراج کن

حذف نویز با مساحتهای کم

cc1 = bwconncomp(imgt1);

stats = regionprops(cc1, ‘Area’);

idx = find([stats.Area] > 500);

imgt2 = ismember(labelmatrix(cc1), idx);

اگر چیزهای دیگری باشند که مساحتشان کوچک باشد حذف کن

imgg{jj,1}=imgt2;

تصویر لب را در ماتریس ذخیره کن

end

t=[];

for jj=2:ff

u=imgg{jj,1}-imgg{jj-1,1};

استخراج حرکت دو تصویر پشت سر هم زمانی

[a b]=find(u==1);

اگر حرکت داشته باشیم

t=[t;[max(a)-min(a) max(b)-min(b)]];

عرض و طول این حرکات را ذخیره کن

end

T1{ii}=t(:,1);

عرضها در یک سلول

T2{ii}=t(:,2);

طولها در یک سلول

end

feature1=[];

for ii=1:numImg

برای هر تصویر

a=T1{ii};

b=T2{ii};

عرض و طولها را در دو متغیر قرار بده

feature1=[feature1 ; [std(a) std(b) median(a) median(b) a(fix(length(a)./2)-2) a(fix(length(a)./2)-1) a(fix(length(a)./2)) a(fix(length(a)./2)+1) a(fix(length(a)./2)+2) b(fix(length(a)./2)-2) b(fix(length(a)./2)-1) b(fix(length(a)./2)) b(fix(length(a)./2)+1) b(fix(length(a)./2)+2) ]];

فضای ویژگیها را بر اساس مدین، انحراف معیار و مقادیر وسط دو ماتریس بساز

%feature1=[feature1 ; [std(a) std(b) median(a) median(b) ]];

end

tt=max(feature1);

ماکزیمم ویژگیها محاسبه

feature=[];

for ii=1:numImg

feature=[feature ;feature1(ii,:)./tt];

همه ویژگیها به ماکزیمم تقسیم تا نرمالیزه شوند

end

out=[];

for ii=1:numImg./TraImg

out=[out ii.*ones(1,TraImg)];

تهیه ماتریس خروجیها بصورت 1*n

end

out1=zeros(size(19,76));

for ii=1:numImg

out1(out(ii),ii)=1;

تهیه ماتریس خروجیها بصورت m*n(مناسب شبکه عصبی)

end

%net=newff(feature’,out1,[13],{‘purelin’ ‘tansig’});

%net=train(net,feature’,out1);

%sim(net,feature(1,:)’)

[result] = multisvm(feature,out’,feature(1,:))

دسته بندی با SVM

به همین راحتی میتوان تشخیص فونم را با متلب و با الگوریتم SVM انجام داد.

فانکشنی را نیز برای این برنامه باید در نظر بگیرید به صورت زیر:

function [result] = multisvm(TrainingSet,GroupTrain,TestSet)

u=unique(GroupTrain);
numClasses=length(u);
result = zeros(length(TestSet(:,1)),1);

%build models
for k=1:numClasses
%Vectorized statement that binarizes Group
%where 1 is the current class and 0 is all other classe
G1vAll=(GroupTrain==u(k));
if G1vAll==ones(size( G1vAll))
G1vAll=[ G1vAll(1:end-1); 2];
end

models(k) = svmtrain(TrainingSet,G1vAll);
end

%classify test cases
for j=1:size(TestSet,1)
for k=1:numClasses
if(svmclassify(models(k),TestSet(j,:)))
break;
end
end
result(j) = k;
end

حالا کافیست برای اجرای برنامه هر بار یک فونم را بصورت زیر بخواهید تا تشخیص دهد:

[result] = multisvm(feature,out’,feature(7,:))

این دستور به این معنی هست که فونم 7ام مربوط به کدام کلاس هست که الگوریتم SVM این کار را انجام می دهد.

سایت متلبی پر از پروژه متلب هست.

0 پاسخ

دیدگاه خود را ثبت کنید

تمایل دارید در گفتگوها شرکت کنید؟
در گفتگو ها شرکت کنید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *