تشخیص فونم ها(لب خوانی) با 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 این کار را انجام می دهد.
سایت متلبی پر از پروژه متلب هست.
سلام مسیر عکس ها را در کدام قسمت باید وارد کنم و چطور میتونم به دیتا ست شما دسترسی داشته باشم ممنون میشم راهنماییم کنید.
با تشکر
سلام. برنامه در همین پست منتشر شده, اما چون داده ها ویدیو هستن و دارای حجم بالایی هستن در فروشگاه متلبی با قیمت ارزان قرار گرفته است.
تشخیص واژه از طریق لب خوانی