به نام خدا : در قسمت اول، به تشخیص چهره از غیر آن پرداختیم؛ در قسمت دوم، تعدادی چهره را ذخیره کردیم و با آن یک شبکه عصبی ساختیم و آن را ذخیره کردیم؛ در این قسمت، از شبکه ساخته شده استفاده می کنیم تا چهره های موجود رو شناسایی کنیم.
بازشناسی چهره انسان با رزبری پای face recognition_قسمت سوم
با دو دستور زیر، یک پوشه جدید می سازیم و وارد آن می شویم :
1 2 |
mkdir facedetect cd facedetect |
فایل nn.xml که در قسمت قبلی ساختیم رو به این پوشه کپی کنید؛ سپس یک فایل با پسوند cpp می سازیم :
1 |
sudo nano fd.cpp |
کد زیر رو بنویسید و ذخیره کنید :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
//g++ nn.cpp -o nn $(pkg-config --libs opencv) -I/usr/local/include -lraspicam -lraspicam_cv #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/objdetect/objdetect.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/ml/ml.hpp> #include "raspicam/raspicam_cv.h" #include <stdio.h> #include <termios.h> #include <unistd.h> #include <fcntl.h> #include "iostream" #include "math.h" using namespace std; using namespace cv; int main(int argc, char** argv) { raspicam::RaspiCam_Cv camera ; Mat image ,gray,frame,img,out; if(!camera.open()){cerr << "error" << endl;return -1;} camera.open(); namedWindow("Display", 0); CascadeClassifier classifier; if(!classifier.load("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml")) { cout << "classifier not found" <<endl; return -1; } CvANN_MLP nn; nn.load("nn.xml","nn"); vector<Rect> faces; while(waitKey(1) < 3){ camera.grab(); camera.retrieve(image); Rect img_rect = Rect(0,0,640,480); img = Mat(image,img_rect); cvtColor(img,gray,CV_BGR2GRAY); classifier.detectMultiScale(gray,faces,1.1,3,0|CV_HAAR_SCALE_IMAGE,Size(30,30),Size(0,0)); float scale =1.0; cout << faces.size() << endl; for (int j = 0 ;j < faces.size();j++) { Point center; Scalar no(0,0,127); Scalar ok(0,127,0); int radius; Rect r = faces[j]; Mat face = Mat(gray,r); resize(face,face,Size(70,70)); Mat data(1,4900,CV_32FC1); uint8_t* dt = face.ptr<uint8_t>(0); for(int i = 0 ;i <= 4899;i++) { data.at<float>(0,i) = *dt; dt++; } data.convertTo(data,CV_32FC1,1.0/255.0); nn.predict(data,out); for (int i = 0; i < 3; i++) { float D = (float)out.at<float>(0, i); if (abs(D - 1) <= 0.1) out.at<float>(0, i) = 1.0; if (abs(D - 0) <= 0.1) out.at<float>(0, i) = 0.0; } cout << out.row(0)<<endl; if(out.at<float>(0,0)==1 & out.at<float>(0,1)==0 & out.at<float>(0,2)==0) { rectangle(img,r,ok,5,8,0); cout << "perrson 1" <<endl; putText(img,"MAR",Point(r.x,r.y-10),FONT_HERSHEY_COMPLEX_SMALL,1.0,Scalar(0,127,0),2,CV_AA); }else if(out.at<float>(0,0)==0 & out.at<float>(0,1)==1 & out.at<float>(0,2)==0) { rectangle(img,r,ok,5,8,0); cout << "person 2" <<endl; putText(img,"MRE",Point(r.x,r.y-10),FONT_HERSHEY_COMPLEX_SMALL,1.0,Scalar(0,127,0),2,CV_AA); }else if(out.at<float>(0,0)==0 & out.at<float>(0,1)==0 & out.at<float>(0,2)==1) { rectangle(img,r,ok,5,8,0); cout << "person 3" <<endl; putText(img,"MAM",Point(r.x,r.y-10),FONT_HERSHEY_COMPLEX_SMALL,1.0,Scalar(0,127,0),2,CV_AA); }else { rectangle(img,r,no,5,8,0); putText(img,"UNKNOWN",Point(r.x,r.y-10),FONT_HERSHEY_COMPLEX_SMALL,1.0,Scalar(0,0,127),2,CV_AA); } } imshow("Display", img); waitKey(1); } camera.release(); return 0; } |
نتیجه شبیه زیر خواهد شد :
روند کار هم به این صورت است که ابتدا چهره ها رو در تصویر پیدا می کنه سپس اون ها رو به اندازه 70*70 تبدیل می کنه. بعدش پیکسل های چهره یافت شده رو در یک سطر می چینه. (یه ماتریس 4900*1 ) سپس اون ماتریس رو به ورودی شبکه nn میده و خروجی متناظرش رو در ماتریس out می ریزه؛ بعدش چک می کنه که چهره شناخته شده، آیا در کلاس های مورد نظر ما هستند یا نه؛ اگر چهره منطبق با چهره های معرفی شده به شبکه باشد: دور چهره، یک مستطیل سبز رنگ می کشه و اسمش رو بالاش می نویسه و اگر چهره نا آشنا باشه، دورش یه مستطیل قرمز رنگ می کشه و بالاش می نویسه نا آشنا.
برای درک سرعت کار این کد ویدئو زیر رو مشاهده بفرمایید : http://www.aparat.com/v/LjMWF
حکمتی از نهج البلاغه (حکمت 150) - ضّد ارزش ها و هشدارها
از کسانی مباش که بدون عمل صالح، به آخرت امیدوار است، و توبه را با آرزوهاي دراز به تأخیر می اندازد. در دنیا چونان زاهدان سخن می گوید، اما در رفتار همانند دنیا پرستان است. اگر نعمت ها به او برسد سیر نمی شود و در محرومیّت قناعت ندارد از آنچه به او رسید شکرگزار نیست و از آنچه مانده زیاده طلب است. دیگران را پرهیز می دهـد امـا خـود پروا نـدارد. به فرمـانبرداري امر می کنـد امـا خود فرمـان نمی برد. نیکوکـاران را دوست دارد، اما رفتارشان را ندارد. گناهکاران را دشمن دارد اماخود یکی ازگناهکاران است. با گناهان فراوان مرگ را دوست نمی دارد، اما در آنچه که مرگ را ناخوشایند ساخت پافشاری دارد. اگر بیمارشود پشیمان می شود، و اگر تندرست باشد سرگرم خوش گذرانی هاست. درسـلامت مغرور و درگرفتـاري نـا امیـداسـت؛ اگر مصـیبتی بـه او رسـد بـه زاري خـدا را می خوانـد. اگر به گشایش دست یافت مغرورانه ازخدا روي بر می گرداند. نفس به نیروي گمان ناروا، بر اوچیرگی دارد، و او با قدرت یقین بر نفس چیره نمی گردد.
براي دیگران کـه گنـاهی کمـتر از او دارنـد نگران، و بیش از آنچه که عمـل کرده امیـدوار است. اگر بی نیـازگردد مست و مغرور شود و اگر تهی دست گردد، مأیوس و سـست شود چون کـارکنـد در آن کوتاهی ورزد، و چون چیزي خواهد، زیاده روی نماید. چون در برابر شـهوت قرارگیرد گنـاه را برگزیـده، توبه را به تـأخیر انـداز، و چون رنجی به او رسـد از راه ملت اسلام دوري گزیند. عبرت آموزي را طرح می کنـد اما خود عبرت نمی گیرد؛ در پند دادن مبالغه می کند اما خود پند پذیر نمی باشد.
سخن بسـیار می گویـد، اما کردارخوب او انـدك است! براي دنیاي زودگـذر تلاش و رقابت دارد اما براي آخرت جاویـدان آسان می گذرد. سود را زیان، و زیان را سود می پنـدارد. از مرگ هراسـناك است اما فرصت را از دست می دهد.
گناه دیگري را بزرگ می شـمارد، اما گناهان بزرگ خود را کوچـک می پنـدارد، طـاعت دیگران را کوچـک و طـاعت خود را بزرگ می داند. مردم راسـرزنش می کند،اما خود را نکوهش نکرده، با خود ریاکارانه برخورد می کند. خوشگذرانی با سرمایه داران را بیشتر از یاد خدا با مستمندان دوست دارد. به نفع خود بر زیان دیگران حکم می کند، اما هرگز به نفع دیگران بر زیان خودحکم نخواهـدکرد، دیگران را هـدایت ،اما خود را گمراه می کنـد. دیگران از او اطـاعت می کننـد، و او مخالفت می ورزد، حق خـود را به تمـام می گیرد، اما حق دیگران را به کمـال نمی دهـد، از غیر خـدا می ترسـد، اما از پروردگـار خود نمی ترسـد.
پیشنهادات برای بهبود برنامه :
1) اگر چهره های شما شناسایی نشد، و یا با خطای زیادی همراه بود :
الف) شرایط نوری داده های آموزشی(همون 30 تا عکس که برای ساخت شبکه عصبی تهیه کردیم) و داده های تست (چهره ای که قراره شناسایی بشه) یکی باشن. مثلا یک چراغ مطالعه روبروی چهره قرار بدید.
ب) اگر قراره تو شرایط نوری مختلفی کار کنید،عکس های آموزشی رو در شرایط نوری متعدد تهیه کنید.
پ) تعداد داده های آموزشی رو بیشتر کنید مثلا به جای 30 عکس،از 60 عکس مختلف برای آموزش شبکه استفاده کنید.
ت) برای دقیق شدن کار،می توانید شبکه را برای چهره های بیشتری آموزش دهید و تعداد حالت های نا شناس رو بیشتر کنید (برای این کار، باید تعداد چهره های دیتابیس رو بیشتر کنید و تعداد نرون های خروجی را به تبع اون افزایش بدید.) برای دانلود تعدادی عکس چهره، به آدرس زیر مراجعه فرمایید : The Database of Faces
ث) تعداد نرون های لایه های میانی هم می توانند دقت کار را بالا ببرند ولی نباید باعث پیچیدگی بی مورد شبکه شوند (پیچیدگی، سرعت رو کم می کنه باید تعادلی بین پیچیدگی و سرعت بر قرار کرد)
2) یکی از کارهایی که برای دقیق تر شدن می توان انجام داد،،افزایش تعداد epoch ها است ولی باید توجه داشت که شبکه برای داده های آموزش شخصی سازی نشود.(over train)
3) یکی دیگر از راه های موجود برای دقیق تر شدن کار، افزایش نوع ویژگی هاست؛ ما از ساده ترین ویژگی یک تصویر(مقادیر پیکسل ها) استفاده کردیم؛ می توانیم از ترکیب چند ویژگی با هم، امنیت را بالاتر ببریم.(مثل فاصله اجزای صورت از یکدیگر، هیستوگرام گرادیان، هیستوگرام جهت لبه ها،تبدیل فوریه و …)
4) برای افزایش سرعت،ابتدا باید کند ترین روند این سیستم، یعنی تشخیص چهره از غیر چهره رو با یک سیستم سریع تر جایگزین کرد.(در حال جستجو برای این مورد هستم)
جهت هر چه مستحکم تر شدن مقام ولایت فقیه و تعجیل درظهور بابای خوبمون مهدی(عج) صلوات
مهمان
با سلام و تشکر.شما برای این پروژه از کدوم مدل رزبری پای استفاده کردید؟ منم متعجب شدم که سرعت رفرش پایین ولیcpuرو۲۶٪!!!؟!.بنظرم اگه سیپیوش اور کلاک بشه سرعت عکس بهتر بشه.ممنون
نویسنده این مطلب
سلام
مدل raspberry3b
چون این برنامه فقط از یک هسته پردازنده استفاده میکنه.از 1/4 قدرت پردازنده استفاده میشه.
اگر بخوایم از بقیه هسته ها هم استفاده کنیم،باید از پردازش موازی استفاده بشه.
مهمان
سلام
هزینه بردای رزبری بالاست،میشه مروژه تشخیص تصویر با دوربین و با برد آردوینوهم انجام داد؟
واینکه مشخصات اردوینو باید جی باشه؟
نویسنده این مطلب
سلام.کار نشد نداره ولی دو تا مشکل هست:
1. سرعت برد های آردینو چقدره؟(کلاک رزبری پای 3 برا بره با 4*1.2 گیگاهرتز)
آیا آردینو با این کلاک هست؟
2.آیا کتابخونه های آماده آردینو برای تشخیص چهره وجود داره؟
احتمالا کتابخونه درست و حسابی پیدا نکنید.
مهمان
سلام دوست عزیز من همینو با پایتون انجام دادم همراه با محیط گرافیکی ، پروژه دانشگاهیمه ولی متاسفانه خطای بالایی داره و همچنین سرعتش افتضاح بود به خواطر همین رزولیشنو کم کردم ولی کلا تشخیص هارو اشتباه می کرد، اگه با c انجام بدم سرعتش بهتره ؟ و پردازش صحیحتره؟ ممنون میشم راهنماییم کنی خیلی احتیاج دارم
نویسنده این مطلب
سلام
کتابخونه opencv هم به زبان c++ نوشته شده.
و از نظر سرعت فرقی نداره.
ولی اگر حلقه تو در تو زیاد دارید،اگر از c یا c++ استفاده کنید،سرعت بیشتره.
*****
در کل،پردازش تصویر با رزبری پای،سرعتش کمه.بهتره با کامپیوتر تست کنید ببینید چجوریه.اونوقت با یه نسبت ساده،میشه سرعت اجرا،روی رزبری رو به دست آورد.
مهمان
سلام ببخشید میشه یه برنامه هم برای تشخیص حروف انگلیسی بزارید ؟
نویسنده این مطلب
سلام.
کتابخونه آماده اش تو اینترنت هست.
سرچ کنید
Ocr
English ocr
مهمان
سلام و عرض ادب..
واسه افزایش تعداد افراد باید چیکار کرد؟
کدوم قسمت برنامه رو باید تغییر داد؟؟
ممنون..
نویسنده این مطلب
سلام
از اون قسمتی که عکس تهیه می کردیم،باید تغییر بدید تا آخر!!!
باید مطلب رو کامل بخونید و خط به خط دنبال کنید تا متوجه بشید.
مهمان
سلام خدا قوت ادامه بدهید لطفا..
مهمان
سلام و خسته نباشید
خیلی عالی و کامل بود
یک سوال داشتم :
من رزبری ۳ دارم وبرای تقویت امواج وای فای از یک دانگل استفاده ولی باز هم پروژه های پردازش تصیورم رو که اجرا میکنم خیلی لگ داره و فرم هایی که میده در حدود ۱ فرم در ۲ ثانیس چی کار کنم که لگش بر طرف بشه . ممنونم
نویسنده این مطلب
سلام
برنامه های پردازش تصویرتون در چه حدیه؟
اگر سنگین باشه،مشکل از ارتباط نیست بلکه از محدودیت قدرت پردازش رزبری هست.مثلا موقع کار،اگر پردازنه رزبری ۱۰۰درصده،یعنی داره همه زورشو میزنه و محدودیت در پردازش دارید
مهمان
به ۵۰ در صد هم نمیرسه وحتی مسایل ساده تر، صفحه ای رو که در ابتدا بالا میارم ، تصویر به حالت پیکسل به پیکسل از بالا تا پایین چیده میشه تا نمایش داده بشه .از هیت سینک استفاده کردم برای جلوگیری از حرارت بالا
نویسنده این مطلب
سلام مجدد.وقتی با کابل شبکه هم وصل میشید،بازم مشکل دارید؟و سوال دیگه اینکه:وقتی هیچ پنجره ای باز نیست،و سی پیو رزبری ۰ هست،باز هم تصویر دیر رفرش میشه؟
مهمان
واقعا کارت عالیه داداش معلومه که خیلی زحمت کشیدی،دارم یه رسبری۳ سفارش میدم تا استارت کارو بزنم ،و اینکه بازم دمت گرم
مهمان
سلام
ممنون عالیه