تطبيق لتحسس حركة الأجسام باستعمال كاميرات المراقبة

هذا البرنامج هو تطبيق دلفي لمراقبة حركة الأجسام أمام  كاميرا المرافبة، البرنامج يقوم بإعطاء إشارة ضوئية أو صوتية للمستخدم، عند  تحرك جسم أمام الكاميراـ كما يمكنه تسجيل التاريخ والوقت لمرور الجسم أمام الكاميرا.  تم استعمال المكتبةOpenCV  الخاصة بمعالجة الصور والفيديوهات  .
Motion detect



ماهي المكتبة OpenCV : 

هي مكتبة تم تطويرها من طرف شركة Intel ، ثم أصبحث مفتوحة المصدر لصالح المطورين، تحتوي هذه المكتبة على أكثر من 2500 خوارزمية ووثائق شاملة وعينة من التعليمات البرمجية للالتقاط وتحليل ومعالجة الصور بواسطة  الكمبيوتر في الوقت الحقيقي . يمكن تحميل هذه المكتبة على هذا الرابط Opencv ، الموقع الرسمي للمكتبة هو opencv.org

المكتبة Opencv في بيئة الدلفي :

 المكتبة Opencv تم كتابتها وتطويرها  أولا بلغة البرمجة C و C++ في أنظمة التشغيل Linux ، Windows و Mac OS X وحاليا هناك مطورون ناشطون للمكتبة يعملون في عدة لغات برمجة منها بايثون ، روبي، ماتلاب ولغات أخرى ، بالنسبة إلى لغة البرمجة دلفي هناك مجموعة من الوحدات تحتوي على إحراءات ودوال ترجمة لتلك المكتبة، يمكن تحميلها على هذا الرابط Delphi-OpenCV تم إنجازها من طرف الروسي Laentir Valetov بمساعدة مواطنه Mikhail Grigorev.

كيفية الوصول واستعمال المكتبة OpenCV في الدلفي : 

بعد تحميل المكتبة وفك الضغط ،هناك ملف مفصل يشرح كيفية إضافتها واستعمالها ، يمكن اختصار الطريقة كما يلي :  نحدد مسار المكتبة للملفات من نوع ."ocv*.pas" و "*.inc "في خصائص المكتبات المستعملة في دلفي كمايلي :
  • في القائمة Tools/Options/  نختار Language بعدها Delphi Options  ثم Librairy

  • إضافة مسار الوحدات الخاصة بالمكتبة Opencv  إلى قائمة البحث في مكتبات الدلفي 
  • نسخ ولصق ملفات المكتبة من نوع dll في مجلد التطبيق أو إضافتها إلى المسار Path، أو وضع تلك الملفات في المجلد system32 .

تصميم التطبيق :

كشف الحركة له أغراض عديدة. يمكنك استخدامه لبدء التسجيل بمجرد رؤية الحركة على كاميرا الحياة البرية أو كاميرا الأمان ، على سبيل المثال تطبيق آخر هو تحسين الأداء. بدلاً من تحليل صورة كاملة ، علينا فقط العمل مع الأجزاء الصغيرة التي تتحرك. مثل تحديد لون السيارات المتحركة فقط .

في هذا الموضوع  ، سننشئ كاشف حركة يعمل بشكل كامل يمكن استخدامه لجميع حالات الاستخدام المذكورة أعلاه. في هذه العملية ، بعض الأوامر المستعملة في معالجة الصور باستخدام OpenCV و Delphi. 

قراءة وإعداد الإطار:

frame := cvQueryFrame(capture);


نحويل الصورة من صيغة Opencv (pIplImage) إلى صيغة Bitmap حتى نتمكن من عرضها على إطار دلفي 
IplImage2Bitmap(frame, framebitmap);
  • نعرض الصورة على العنصر pb1) PaintBox):
pb1.Canvas.StretchDraw(pb1.ClientRect, framebitmap);


  • نقوم بإنشاء صورة فارغة لتخرين الحركة ثم نحولها إلى صورة من نوع Bitmap ونعرضها على الإطار الرئيسي في الدلفي إلى جانب الصورة الأصلية:
if not Assigned(motion) then begin motion := cvCreateImage(CvSize(frame^.Width, frame^.Height), 8, 3); cvZero(motion); motion^.origin := frame^.origin; end; update_mhi(frame, motion, 30); IplImage2Bitmap(motion, framebitmap);



نفرض أن في الإطار الأول  الفيديو يحتوي على الخلفية فقط ولا يحتوي على أي حركة - لذلك ، يمكننا نمذجة خلفية تدفق الفيديو  باستخدام الإطار الأول فقط من الفيديو وهذا  ما نلاحظه في الإجراء : 
  
procedure TFrmMain.update_mhi(img, dst: pIplImage; diff_threshold: Integer); Var timestamp: double; size: TCvSize; i, idx1: Integer; silh: pIplImage; seq: pCvSeq; comp_rect: TCvRect; count, angle: double; center: TCvPoint; magnitude: double; Color: TCvScalar; idx2: Integer; begin timestamp := GetTickCount / CLOCKS_PER_SEC; // الزمن الحالي بالثواني size := CvSize(img^.Width, img^.Height); // get current frame size idx1 := last; // حجز الذاكرة للصور في البداية أو // إعادة الحجز إذا تغير حجم الإطار if (not Assigned(mhi)) or (mhi^.Width <> size.Width) or (mhi^.Height <> size.Height) then begin if not Assigned(buf) then begin buf := AllocMem(N * sizeof(pIplImage)); ZeroMemory(buf, N * sizeof(pIplImage)); end; for i := 0 to N - 1 do begin cvReleaseImage(buf[i]); buf[i] := cvCreateImage(size, IPL_DEPTH_8U, 1); cvZero(buf[i]); end; cvReleaseImage(mhi); cvReleaseImage(orient); cvReleaseImage(segmask); cvReleaseImage(mask); mhi := cvCreateImage(size, IPL_DEPTH_32F, 1); cvZero(mhi); // clear MHI at the beginning orient := cvCreateImage(size, IPL_DEPTH_32F, 1); segmask := cvCreateImage(size, IPL_DEPTH_32F, 1); mask := cvCreateImage(size, IPL_DEPTH_8U, 1); end; cvCvtColor(img, buf[last], CV_BGR2GRAY); //تحويل الإطار إلى االرمادي idx2 := (last + 1) mod N; // index of (last - (N-1))th frame last := idx2; silh := buf[idx2]; cvAbsDiff(buf[idx1], buf[idx2], silh); //الحصول على الفرق بين الإطارات cvThreshold(silh, silh, diff_threshold, 1, CV_THRESH_BINARY); // and threshold it cvUpdateMotionHistory(silh, mhi, timestamp, MHI_DURATION); // update MHI // تحويل MHI إلى صورة زرقاء cvCvtScale(mhi, mask, 255. / MHI_DURATION, (MHI_DURATION - timestamp) * 255. / MHI_DURATION); cvZero(dst); cvMerge(mask, 0, 0, 0, dst); // حساب اتجاه التدرج الحركي وقناع الاتجاه الصحيح cvCalcMotionGradient(mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3); if not Assigned(storage) then storage := cvCreateMemStorage(0) else cvClearMemStorage(storage); // حركة القطعة: الحصول على تسلسل مكونات الحركة //segmask عبارة عن خريطة مكونات لحركة معينة. وهو غير مستخدم فيما بعد seq := cvSegmentMotion(mhi, segmask, storage, timestamp, MAX_TIME_DELTA); // التكرار من خلال مكونات الحركة, // تكرار آخر (i = -1) يتوافق مع الصورة بأكملها (حركة عالمية) for i := -1 to seq^.total - 1 do begin if (i < 0) then begin // case of the whole image comp_rect := CvRect(0, 0, size.Width, size.Height); Color := CV_RGB(255, 255, 255); magnitude := 100; end else begin //مكون الحركة من الرتبة i comp_rect := pCvConnectedComp(cvGetSeqElem(seq, i))^.rect; if (comp_rect.Width + comp_rect.Height < (1000-10*sb1.Position)) then // reject very small components continue; Color := CV_RGB(255, 0, 0); magnitude := 30; end; // تحديد مكون منطقة الاهتمام ROI cvSetImageROI(silh, comp_rect); cvSetImageROI(mhi, comp_rect); cvSetImageROI(orient, comp_rect); cvSetImageROI(mask, comp_rect); // حساب الاتجاه angle := cvCalcGlobalOrientation(orient, mask, mhi, timestamp, MHI_DURATION); angle := 360.0 - angle; // ضبط للصور ذات الأصل أعلى- اليسار count := cvNorm(silh, 0, CV_L1, 0); // حساب عدد النقاط في صورة ظلية ROI cvResetImageROI(mhi); cvResetImageROI(orient); cvResetImageROI(mask); cvResetImageROI(silh); //تحقق من حالة الحركة الصغيرة if (count < comp_rect.Width * comp_rect.Height * 0.05) then continue; // ارسم ساعة مع سهم يشير إلى الاتجاه center := CvPoint((comp_rect.x + comp_rect.Width div 2), (comp_rect.y + comp_rect.Height div 2)); cvCircle(dst, center, cvRound(magnitude * 1.2), Color, 3, CV_AA, 0); cvLine(dst, center, CvPoint(cvRound(center.x + magnitude * cos(angle * CV_PI / 180)), cvRound(center.y - magnitude * sin(angle * CV_PI / 180))), Color, 3, CV_AA, 0); end;


خصائص التطبيق 

  •   نظام التشغيل : ويندوز 7 فما فوق
  •   لغة البرمجة : دلفي 10.3 ريو
  • تشقير التطبيق :  (64bits)
  •   حجم التطبيق 3 ميغابايت 
  • كود فك الضغط : 0000


 ويمكن تحميل التطبيق والكود سورس على الروابط التالية
الكود سورس : تحميل
التطبيق : تحميل التطبيق



ليست هناك تعليقات:

إرسال تعليق

المشاركات الشائعة