بطريقة ما سقطت في أيدي مهمة الاختبار. سادت الاهتمام الأكاديمي وقررت المشاركة في هذه المهمة. حل بلدي لا يدعي أنه الأمثل والصحيح. كنت فضولية فقط لحلها.
مصدر البيانات
جوهر المهمة هو كتابة برنامج يحدد ما إذا كان قد تم ربط النخيل بالماسح الضوئي بواسطة صورة صور من الماسح الضوئي لأوردة النخيل.
البيانات الأولية - العديد من الصور ذات النتيجة المعروفة.

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


خوارزمية
خوارزمية تحليل الصور بسيطة للغاية. للبدء ، قمت بإنشاء فئة ImageAnalyser بالواجهة التالية
class ImageAnalyser { public: ImageAnalyser(); explicit ImageAnalyser(const QImage&); bool analyze(const QImage&); bool analyze(); std::vector<std::vector<int>> data(); virtual ~ImageAnalyser(); };
داخل هذا الفصل ، قررت تقسيم الصورة بشكل مشروط إلى 4 أجزاء لكل مصدر ضوء. ولكل صورة ، احسب متوسط السطوع بالنسبة لمحور X و Y. هذا واضح في الصورة أدناه.

نتيجة لذلك ، حصلنا على ثمانية رسوم بيانية بمستوى سطوع متوسط.

بعد ذلك ، تحتاج إلى تحليل هذه الرسوم البيانية. قررت استخدام وظيفة الارتباط من خلال مقارنة الرسوم البيانية الناتجة مع بعض الرسم البياني "المثالي". الرسم البياني المثالي في هذه الحالة هو مجرد مستطيل ، أحصل عليه بالطريقة التالية:
std::vector<int> ImageAnalyser::prepare_ideal_array(const std::vector<int>& array) { unsigned long min = static_cast<unsigned long>(array.size() * 0); unsigned long max = static_cast<unsigned long>(array.size() * 0.45); int ideal_value = 100; std::vector<int> ideal; ideal.resize(array.size()); for(unsigned long i = min; i < max; ++i) { ideal[i] = ideal_value; } return ideal; }
لمقارنة الرسوم البيانية ، وبالتالي ، الحصول على قيمة الارتباط ، استخدمت دالة gsl_stats_correlation التي سرقتها بصدق من مكتبة جنو العلمية .
double ImageAnalyser::gsl_stats_correlation(const std::vector<int>& data) { std::vector<int> ideal = prepare_ideal_array(data); const int stride1 = 1; const int stride2 = 1; double sum_xsq = 0.0; double sum_ysq = 0.0; double sum_cross = 0.0; double mean_x = data[0]; double mean_y = ideal[0]; for (unsigned int i = 1; i < data.size(); ++i) { double ratio = i / (i + 1.0); double delta_x = data[i * stride1] - mean_x; double delta_y = ideal[i * stride2] - mean_y; sum_xsq += delta_x * delta_x * ratio; sum_ysq += delta_y * delta_y * ratio; sum_cross += delta_x * delta_y * ratio; mean_x += delta_x / (i + 1.0); mean_y += delta_y / (i + 1.0); } double r = sum_cross / (sqrt(sum_xsq) * sqrt(sum_ysq)); return r; }
بعد ذلك ، تحتاج فقط إلى تحليل قيم الارتباط. قررت أنه إذا كانت قيمة ارتباط واحدة على الأقل أقل من 0.5 ، فإن راحة اليد ليست متصلة بالمستشعر أو تكون غير متصلة بشكل جيد.
bool ImageAnalyser::is_good(const vector<double>& correlation, const vector<int>& maximums) { bool result = true; double min_corr = *std::min_element(correlation.begin(), correlation.end()); if (min_corr < 0.5) { result = false; } double min_val = *std::min_element(maximums.begin(), maximums.end()); if (min_val < 30) { result = false; } return result; }
يتبين أيضًا من الكود أنه يتم إجراء تحليل لمستوى السطوع - إذا كانت القيمة أقل من 30 ، فإننا نعتقد أيضًا أن النخلة غير متصلة.
كومة من التقنيات المستخدمة
- C / c ++
- كيو تي الخالق
- QtCharts
- مكتبة جنو العلمية
شفرة المصدر
https://github.com/techlinked/PalmDetector.git