بسم الله الرحمن الرحيم .
الموضوع داخل مدونة دوال. وأيضا يسعدني ان اشكر كل من ساعدني في هذا الموضوع .
openCV
مكتبة متخصصة في “computer vision” وتتميز بأنها مفتوحة المصدر وتعمل على أنظمة linux و windows و mac ولقد تم كتابتها بلغة c/c++ وتدعم أيضا لغات أخرى python و rubi و matlab.
وتركز المكتبة على تطبيقات ال real time ,ويميزها سهولتها وإمكانية كتابة برامج كاملة عن طريقها وفي وقت قصير .وتتوفر للمكتبة أكثر من خمسمائة دالة تغطي مساحات عديدة للرؤية تشمل فحص المنتج والتصوير الطبي والأمن وواجهة المستخدم ومعايرة الكاميرا والروبوتات...الخ.
ما هو الـ “computer vision” ؟
يمكننا ترجمتها "حاسة بصر الحاسب الآلي" أو "رؤية الحاسب الآلي" أو ما تراه مناسبا .ونعرفه بأنه علم برمجي يهتم بطرق تحويل بيانات الصور والفيديو إلى معلومات وقرارات أو إعادة تمثيل هذه البيانات من جديد . وتكون المعلومات والقرارات على النحو التالي : "هل يوجد شخص في الصورة" أو "هل البصمات متطابقة في الصورتين"...الخ.أما إعادة تمثيل البيانات فتكون على النحو التالي: "تحويل الصورة الملونة إلى صورة رمادية" أو "إزالة حركة الكاميرا من الفيديو" ...الخ.
معمارية openCV
CXCORE
يحتوي على تراكيب البيانات(data structure) , والمصفوفات (matrix algebra) وتحويل البيانات واستمرارية الكائن و إدارة الذاكرة ومعالجة الأخطاء و التحميل الديناميكي للترميز و رسمها والنصوص واسس الرياضيات .
CV
معالجة الصور وتحليل بنية الصور وتتبع الحركة ومعايرة الكاميرا .
Machine Learning (MLL)
وتحليل البيانات والإحصائيات بالإضافة إلى أدوات أخرى .
HighGUI
واجهة المستخدم الرسومية وتخزين وعرض الصور والفيديو .
CvAux
توفر عمل Eigen Objects (EO) و HMM (Hidden Markov Models) و هما طريقتان مشهورتان من طرق التعرف على الوجه لهما خاصية مشتركة أنهما ينتميان لعائلة التعرف على الوجه local
-التعرف على الحركات أو تحديدها من خلال ما يسمى stereo vision أي عندما يكون لدينا أكثر من كاميرا.
-تساعد على توفير خدمة تطابق الأشكال (صور أشخاص أو أمكنة ....) بطريقة تطابق حواف المناطق region contour .
- تتبع حركة العين و الفم.
-التتبع في مجال 3d.
-المراقبة باستخدام الكاميرا .
- تعديل الكاميرا ) أو معايرة الكاميرا) يعني أننا يجب أن نجد العلاقة بين إحداثيات النقطة في الحقيقة و إحداثياتها في الصورة التي أخذت بالكاميرا .
-معرفة هيكل أي جسم و ذلك لاستخدامه في التعرف على الأشخاص مثلا أو تتبع حركتهم ...الخ .
openCV وتكاملها مع Qt
توفر لك openCV حلول في معالجة الصور وقراءة البيانات لا يوفرها Qt بينما توفر لك Qt حلول في مجالات أخرى لا توفرها openCV فلهذا جعل كلتا المكتبتين تتكامل فيما بينهما أمرا مهما للبعض منا .
معلومة: يمثل IplImage كائن الصور في openCV بينما يمثل QImage كائن الصور في Qt .
تحويل الصور من IplImage إلى QImage والعكس كذلك :
في الغالب لن تحتاج الا لهذه الخطوة لتصل الى التكامل المنشود بين Qt و openCV .
يتوجب تطابق صيغ بيانات الصورة بين IplImage و QImage فمثلا لو كان نظام الألوان bgr في IblImage فإن الصورة لن تظهر بألوانها الصحيحة في QImage لأن الاخير يعتمد على rgb .
مثال على طريقة التحويل :
IplImage* cvImage=cvLoadImage("C:/try/c1.png");//تحميل الصورة
cvCvtColor(cvImage,cvImage,CV_BGR2RGB);//convert image data from bgr to rgb
QImage qtImage((uchar*)cvImage->imageData,cvImage->width,cvImage->height,cvImage->widthStep,QImage::Format_RGB888); //get QImage by read image data in IplImage
لقد قمنا بتحويل صيغ البيانات الى rgb ليقرأها QImage على الشكل QImage::Format_RGB888 .
ويمكن الاستغناء عن السطر الثاني واستبداله بدالة أخرى متوفرة في QImage :
IplImage* cvImage=cvLoadImage("C:/try/c1.png");//تحميل الصورة
QImage qtImage((uchar*)cvImage->imageData,cvImage->width,cvImage->height,cvImage->widthStep,QImage::Format_RGB888);//get QImage by read image data in IplImage
qtImage.rgbSwapped();//convert from rgb to bgr
هذه المرة أبقينا على IplImage بدون تغيير في صيغة بياناتها و حولنا صيغة بيانات الصورة في QImge من rgb الى bgr .
مثال لنقل صورة من QIamge إلى IplImage :
QImage qtImage("c:/try/c1.png");
IplImage* cvImage = cvCreateImage(cvSize(qtImage.width(), qtImage.height()), 8, 4);// create empty image with same data format of QImage
cvImage->imageData = (char*)qtImage.bits();//get IplImage by read image data in QImage
في Qt لا توجد طريقة مباشرة لتحويل الصورة الى اللون الرمادي بينما يتوفر ذلك في openCV والسؤال هنا كيف نقوم بتحويل هذه الصور الرمادية الى QImage ؟
الحل الأفضل هو نسخ البكسلات من IplImage إلى QImage بكسل تلو البكسل .
طريقة صنع دالة تنسخ على مستوى البكسلات للصور الرمادية:
/*
Imالصورة المنسية=
pIplImage =الصورة القديمة
qImage = الصورة الجديدة
*/
IplImage* im=cvLoadImage("c:/try/c1.png");// تحميل الصورة الى "الصورة المنسية"
IplImage* pIplImage=cvCreateImage(cvSize(im->width,im->height),im->depth,1);//انشاء "الصورة القديمة" على انها رمادية
cvCvtColor(im,pIplImage,CV_BGR2GRAY);//عملية نسخ "الصورة المنسية" وتحويلها الى رمادي وحفظها في "الصورة القديمة"
int w = pIplImage->width;// الحصول على العرض من "الصورة القديمة"
int h = pIplImage->height;//الحصول على الارتفاع من "الصورة القديمة"
Qimage qImage = QImage(w, h, QImage::Format_RGB32);//انشاء "الصورة جديد" وفقا لعرض وارتفاع "الصورة القديمة"
for(int x = 0; x < pIplImage->width; ++x)
{
//يتم قراءة البكسلات عامود تلو الآخر
for(int y = 0; y < pIplImage->height; ++y)
{
CvScalar color = cvGet2D(pIplImage, y, x); // x و y الحصول على بيانات البكسل من "الصورة القديمة" وفق الاحداثيات
int v = color.val[0];
qImage.setPixel(x, y, qRgb(v,v,v));//نسخ البكسل الرمادي إلى "الصورة الجديدة"
}
}
تنبيه : يتوفر في الملف المرفق QtCv دالة لنسخ الصور على مستوى البكسلات سواء الرمادية أو الملونة يفضل ان تطلع عليها .
ملاحظة: في الاصدار الثاني من مكتبة openCV قد تواجهك ان بعض الدوال قد لاتعمل مع ال slots أمثال cvCvtColor في هذه الحال لديك مجموعة حلول منها : إنشاء thread داخل ال slot لتنفيذ العملية أو استخدم QtConcurrent::run() او انتقل الى openC V الإصدار الأول .
المرفقات
ملاحظة أخيرة : لم أتطرق لطريقة تثبيت المكتبة مع Qt لانها مشابهة لمعظم المكتبات ان لم تكن اسهل .
والسلام عليكم ورحمة الله وبركاته .