موردکاوی: پردازش تصویر در هدوپ

مبحث پردازش تصویر در هدوپ بحث جذابی است که نمی‌توان مثال‌ها و ابزارهای بسیاری برای آن پیدا کرد. زیرا که نه تنها پیچیدگی های راه اندازی و استفاده از OpenCV را می بایست متحمل شد، بلکه مدل پردازشی پیش‌فرض هدوپ یعنی MapReduce نیز اصول و قواعد پیچیده‌ای دارد که می‌تواند کار را چندبرابر سخت کند. ما در این مقاله قصد داریم مثالی در پردازش تصویر(تشخیص چهره) را به کمک هدوپ تحلیل و پیاده‌سازی کنیم.

برای کار با الگوریتم های پردازش تصویر در هدوپ ۳ کتابخانه مشهور زیر وجود دارند:

دو کتابخانه HIPI و MIPr از کتابخانه استاندارد پردازش تصویر OpenCV استفاده می‌کنند و در‌واقع واسطی بین OpenCV و جاوا و در نهایت هدوپ هستند. اما کتابخانه OpenIMAJ به تنهایی، خود کتابخانه ای جهت پردازش تصویر در جاوا می‌باشد و از OpenCV استفاده نمی کند. نکته‌ای که در کتابخانه‌های HIPI و MIPr وجود دارد این است که HIPI مبتنی بر نسخه ۱ هدوپ پیاده‌سازی شده است در صورتی که MIPr از نسخه ۲ هدوپ استفاده می کند. به همین علت ما نیز در این مثال از کتابخانه MIPr استفاده خواهیم کرد. همچنین دیتاست مورد استفاده ما در این مثال LFW است که مجموعه‌ای با حجم های متفاوت از چهره‌های افراد می باشد. ما در این مثال از مجموعه ۱۰۰۰ تایی این دیتاست استفاده می کنیم.

در ابتدای این مثال، ابتدا بدون استفاده از هدوپ الگوریتم تشخیص چهره را با زبان جاوا و کتابخانه OpenCV به صورت زیر می نویسیم:

long startTime = System.currentTimeMillis();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("\nRunning FaceDetector");
String[] files = {"multiface.png","multiface2.png","multiface3.png", "multiface4.png"};
CascadeClassifier faceDetector = new CascadeClassifier("haarcascade_frontalface_alt.xml");
for (int i =0;i<files.length;i++){
Mat image = Highgui.imread(files[i]);
 
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);

System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
 
for (Rect rect : faceDetections.toArray()) {
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}
String filename = "ouput"+i+".png";
System.out.println(String.format("Writing %s", filename));
Highgui.imwrite(filename, image);
}
long endTime   = System.currentTimeMillis();
long totalTime = (endTime - startTime);
System.out.println("Totaltime(ms) : "+totalTime);

در کد بالا ۴ عکس به برنامه داده می‌شود تا تعداد چهره‌های موجود در عکس شناسایی شود. ابتدا ۴ عکس در آرایه files قرار میگیرد که بیانگر عکس هایی است که در مسیر پروژه قرار دادیم. برای تشخیص چهره می بایست کلاس CascadeClassifier که یکی از کلاس های OpenCV است را به همراه فایل xml مربوط به آموزش الگوریتم تعریف کنیم. در مورد چیستی این فایل xml می‌توانید به مستندات مربوط به OpenCV مراجعه کنید. در این کد به ازای هر عکسی که در آرایه وجود دارد عملیات تشخیص تکرار می شود. در‌واقع نتایج عملیات Classification در ماتریسی به نام FaceDetection ذخیره می‌شود. تعداد آرایه های موجود در این ماتریس بیانگر تعداد چهره‌هایی است که در یک تصویر شناسایی شده است. در مرحله بعد از طریق مقادیر موجود در ماتریس به دور چهره ای که در تصویر شناسایی شده است مستطیلی کشیده می‌شود که حاکی از تشخیص چهره موردنظر است. در نهایت تصویر جدیدی که برروی آن مستطیل رسم کرده‌ایم با نام جدید ذخیره می شود. دقت شناسایی چهره، ارتباط مستقیم به فایل xml آموزش و دفعات اجرای برنامه دارد. قبل از اجرای برنامه ابتدا قصد داریم برنامه را با یک عکس تست کنیم. نتیجه را در جدول شماره ۱ مشاهده کنید.

پس از انجام تست اول حالا قصد داریم دو اجرای بالا را در هدوپ پیاده‌سازی و تست کنیم. برای اینکار ابتدا هدوپ را در حالت Pseudo-Distributed در VirtualBox راه اندازی کنیم و در این حالت اجرای برنامه را تست کنیم. همانطور که توضیح داده شد در این برنامه از موتور پردازشی MapReduce استفاده شده است. برای اجرای عملیات تشخیص چهره به صورت موازی و توزیع شده تابع map مربوط را به صورت زیر می نویسیم:

protected void map(NullWritable key, MatImageWritable value, Context context) throws IOException, InterruptedException {
            Mat image = value.getImage();

            if (image != null) {

                CascadeClassifier faceDetector = null;
faceDetector = new CascadeClassifier("/data/haarcascades/haarcascade_frontalface_alt.xml");

                MatOfRect faceDetections = new MatOfRect();
                faceDetector.detectMultiScale(image, faceDetections);

                for (Rect rect : faceDetections.toArray()) {
                    Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255), 3);
                }

                MatImageWritable matiw = new MatImageWritable(image);

                matiw.setFormat("jpg");
                matiw.setFileName(value.getFileName() + "_result");
                context.write(NullWritable.get(), matiw);
            }
}

در کد بالا الگوریتم تشخیص چهره به همان صورت است که در مثال قبلی توضیح داده شد ولی نکاتی وجود دارد که آنرا در ادامه شرح خواهیم داد.

در نوع اجرای موازی این الگوریتم، پوشه تصاویر به برنامه داده می‌شود تا هر تابع Map تعدادی از این تصاویر را برروی ماشین‌های کلاستر هدوپ پردازش کند. هر تصویر از طریق متغیر سریالی شده MatImageWritable در کد برنامه قابل دسترس است و در‌واقع به جای آرایه ای که در اجرای اول بود اینکار ورودی با مدیریت هدوپ از طریق این متغیر به کدبرنامه ارسال می شود. به دلیل اینکه این برنامه فاقد فاز Reduce است نتیجه تابع Map هر ماشین که تصویر جدید می‌باشد به هدوپ ارسال می شود و هدوپ تصاویر را در خروجی ذخیره می کند. این الگوریتم را ابتدا با یک عکس و سپس با ۴ عکس اجرا می‌کنیم تا شرایط یکسان با اجرای معمولی الگوریتم وجود داشته باشد.

نکته‌ای که در اینجا می بایست دقت کنید این است که هدوپ در حالت Pseudo-Distributed در VirtualBox راه اندازی و این برنامه برروی آن اجرا شده است. لذا انتظار نداشته باشید نتیجه‌ای که این اجرا در مقایسه با حالت عادی الگوریتم دارد نه تنها برابر باشد بلکه بهتر باشد. نتیجه را در جدول شماره ۱ مشاهده کنید.

در نهایت می‌خواهیم این الگوریتم را در حالت Fully-Distributed هدوپ اجرا کنیم. برای اینکار ۲ سرور را با مشخصات ۴ گیگابایت رم، ۸ هسته سی پی یو ۲.۱ گیگاهرتز،۱ ترابایت دیسک سخت و ۱۰۰ مگابیت سرعت شبکه، پیکربندی و هدوپ را برروی آن راه اندازی می کنیم. اگر نمی‌دانید چطور هدوپ را در حالت چند گره راه اندازی کنید این مقاله را مطالعه کنید. برنامه‌ای که در اجرای دوم نوشته بودیم را اینبار برروی کلاستر ۲ گره ای که پیکربندی کرده ایم، اجرا می کنیم. تعداد عکس‌های ورودی ما این بار در ابتدا ۱۰۰ عکس و سپس ۱۰۰۰ عکس خواهد بود. نتیجه اجرای سوم را در جدول شماره ۱ مشاهده کنید.

مسئلهزبان برنامه نویسینوع اجراتعداد تصاویرزمان اجرا(میلی ثانیه)
تشخیص چهرهجاواغیرموازی1847
تشخیص چهرهجاواغیرموازی41776
تشخیص چهرهجاواشبه موازی

11160
تشخیص چهرهجاواشبه موازی415900
تشخیص چهرهجاواموازی100562
تشخیص چهرهجاواموازی1000486

جدول شماره 1

از موردکاوی بالا می‌توان این نتیجه را گرفت که:
۱. هدوپ به خوبی و با سرعت بالاتر می‌تواند فرآیند پردازش تصویر را به صورت موازی و توزیع شده در وسعت کلان انجام دهد.
۲. هدوپ برای کار بر روی یک سیستم چه به صورت واقعی و چه به صورت شبیه سازی شده ساخته نشده است و ماهیت اجرای موازی را زیرسوال و نتیجه مسأله را اشتباه و گاهی اوقات غیرقابل اعتماد می سازد.
۳. هدوپ در مسائلی که معیارهای کلان داده برقرار نیستند نتیجه عکس خواهد داشت. به این صورت که داده‌هایی که نمی‌توان به آن‌ها کلان داده گفت اگر از طریق هدوپ مورد تحلیل و پردازش قرار گیرند، هدوپ نمی تواند کارایی چندان مناسبی داشته باشد. به دلیل اینکه هدوپ برای تحلیل و پردازش داده‌های ساده و غیرکلان ساخته نشده است و ابزارهای بهتری برای اینکار وجود دارند.

نکته ۱ : کتابخانه MIPr وظیفه معرفی و انتقال تنظیمات برنامه، انواع متغیر، قالب های داده‌ای کار با تصاویرو عملیات خواندن و نوشتن تصویر را دارد و هسته اصلی کار یعنی تشخیص تصویر(چهره) بر عهده OpenCV می باشد.

نکته ۲ : دقت کنید که کتابخانه‌های OpenCV نظیر فایل‌های .so و فایل‌های موردنیاز دیگر به دلیل اجرا شدن در حالت موازی و توزیع شده در هدوپ می بایست ابتدا در HDFS ذخیره شوند و به صورت فایل‌های کش توسط متد AddCacheFile به تنظیمات Job معرفی شوند تا برنامه بتواند در هر ماشین از این کتابخانه‌ها استفاده کند.

نکته ۳ : این الگوریتم فقط برروی فرمت های استاندارد تصاویر مانند Jpeg و PNG تست شده است.

نکته ۴ : برای پردازش نقاط دیگر از صورت مثل بینی،چشم،گوش و لبخند فقط کافی است فایل آموزش xml در کلاس CascadeClassifier را تغییر دهید.

نکته ۵ : نتایج ممکن است در پیکربندی ها و تغییرات گوناگون متفاوت باشند.

از سرورهای ما برای اجرای پروژه های داده های کلان خود بدون اینکه درگیر پیچیدگی نصب شوید استفاده کنید. برای سفارش اینجا را کلیک کنید.
ما حتی می توانیم کلاستر و سرورهای هدوپ را برای شما ایجاد کنیم. برای درخواست راه اندازی اینجا را کلیک کنید.
اگر نیاز به مشاوره و یا کلاس آموزشی داشتید به اینجا مراجعه کنید.

لیست نظرات

پاسخ دهید

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