باستخدام Opencv كيفية اكتشاف مربع في الصورة أثناء إزالة الكائنات المطبوعة داخل الصندوق؟
-
02-01-2020 - |
سؤال
أحاول تطوير تطبيق فرز الصناديق في كيو تي واستخدام opencv.أريد قياس عرض وطول الصندوق.
كما هو موضح في الصورة أعلاه، أريد اكتشاف الخطوط الخارجية فقط (أي.حواف الصندوق)، مما سيعطيني عرض وطول الصندوق، بغض النظر عما هو مطبوع داخل الصندوق.
ما حاولت:
أولا حاولت استخدام
Findcontours()
وكفاف محدد بمساحة قصوى، ولكن محيط الحافة الخارجية غير مغلق (مكسور في مكان ما في الإخراج الذكي) عدة مرات وبالتالي لا يتم اكتشافه ككفاف.على الرغم من أن تحويل الخط يعطيني عددًا كبيرًا جدًا من الأسطر، لا أعرف كيفية الحصول على أربعة أسطر فقط مما يثير اهتمامي من ذلك.
لقد جربت الخوارزمية الخاصة بي كـ،
تحويل الصورة إلى مقياس رمادي.
خذ عمودًا واحدًا من الصورة، وقارن كل بكسل بالبكسل التالي التالي لذلك العمود، إذا كان الاختلاف في القيمة أكبر من بعض العتبات (على سبيل المثال 100) التي ينتمي إليها البكسل إلى الحافة، لذا قم بتخزينها في صفيف.افعل ذلك لجميع الأعمدة وسيعطي الخط العلوي للمربع موازيًا للمحور x.
اتبع نفس الإجراء، ولكن من العمود الأخير والصف الأخير (أي.من الأسفل إلى الأعلى)، سيعطي الخط السفلي الموازي للمحور x.
وبالمثل ابحث عن خطوط موازية للمحور y أيضًا.الآن لدي أربع مصفوفات من النقاط، واحدة لكل جانب.
وهذا يعطيني نتائج جيدة إذا تم وضع الصندوق بطريقة تجعل جوانبه متوازية تمامًا مع المحورين X وY.إذا تم وضع الصندوق ولو قليلاً في اتجاه ما، فإنه يعطيني خطوطًا قطرية واضحة كما هو موضح في الصورة أدناه.
كما هو موضح في الصورة أدناه، قمت بإزالة أول 10 نقاط وآخر 10 نقاط من جميع مصفوفات النقاط الأربع (المسؤولة عن رسم الخطوط القطرية) ورسمت الخطوط، وهو ما لن ينجح عندما يميل المربع أكثر وستحدث أخطاء أيضًا في القياسات .
والآن سؤالي هو،
هل هناك أي طريقة أبسط في opencv للحصول على الحواف الخارجية (المستطيل) للصندوق فقط والوصول إلى الأبعاد، وتجاهل أي شيء مطبوع على الصندوق وموجه في أي اتجاه؟
أنا لا أطلب بالضرورة تصحيح/تحسين الخوارزمية الخاصة بي، ولكن نرحب أيضًا بأي اقتراحات بشأن ذلك.آسف لمثل هذا المنصب الكبير.
المحلول
أود أن أقترح الخطوات التالية:
1:اصنع صورة قناع باستخدام cv::inRange()
(توثيق) لتحديد لون الخلفية.ثم استخدام cv::not()
لعكس هذا القناع.هذا سوف يعطيك الصندوق فقط.
2:إذا لم تكن قلقًا بشأن الظل وتأثيرات العمق التي تجعل قياسك غير دقيق، فيمكنك المتابعة فورًا في محاولة الاستخدام cv::findContours()
مرة أخرى.قمت باختيار أكبر كفاف وتخزينه cv::rotatedRect
.
3:هذا cv::rotatedRect
سيعطيك RotatedRect.size الذي يحدد العرض والارتفاع للمربع الخاص بك بالبكسل
نصائح أخرى
نظرا لأن المربع يتم وضعه في خلفية متباينة، يجب أن تكون قادرا على استخدام عتبة Otsu.
- عتبة الصورة (استخدام طريقة otsu)
- تصفية أي بكسل ضائحي خارج منطقة مربع (دعونا نأمل أن لا تحصل على العديد من هذه البكسلات ويمكن إزالتها بسهولة مع متوسط أو مرشح مورفولوجي)
- العثور على ملامح
- الجمع بين جميع نقاط كفاف والحصول على بدن محدب الخاص بهم (IDEA هنا للعثور على منطقة المحدبة التي تحتم كل هذه المحيطات في منطقة مربع بغض النظر عن اتصالها)
- قم بتطبيق تقريب مضلع (حوالي polickpolydp) إلى هذا بدن محدب وتحقق مما إذا كنت تحصل على رباعية
- إذا لم تكن هناك تشوهات منظور، يجب عليك الحصول على مستطيل، وإلا فسيتعين عليك تصحيحه
- إذا حصلت على مستطيل، لديك أبعادها.يمكنك أيضا العثور على مستطيل المساحة الدنيا (MINAREARETED) من المحدبة، والتي يجب أن تعطيك مباشرة RotatedRect