Entah bagaimana saya jatuh ke tangan tugas ujian. Minat akademis menang dan saya memutuskan untuk duduk di tugas ini. Solusi saya tidak mengklaim optimal dan benar. Saya hanya ingin menyelesaikannya.
Sumber data
Inti dari tugas ini adalah untuk menulis program yang menentukan apakah telapak tangan dilampirkan ke pemindai oleh gambar gambar dari pemindai urat nadi.
Data awal - beberapa gambar dengan hasil yang diketahui.

Hasil
Program dengan antarmuka grafis dengan kemampuan untuk memilih gambar dari daftar. Setelah memilih gambar dianalisis dan setelah analisis hasilnya ditampilkan dalam bentuk tulisan Baik atau Buruk .


Algoritma
Algoritma analisis gambar cukup sederhana. Untuk memulai, saya membuat kelas ImageAnalyser dengan antarmuka berikut
class ImageAnalyser { public: ImageAnalyser(); explicit ImageAnalyser(const QImage&); bool analyze(const QImage&); bool analyze(); std::vector<std::vector<int>> data(); virtual ~ImageAnalyser(); };
Di dalam kelas ini, saya memutuskan untuk membagi gambar menjadi 4 bagian untuk setiap sumber cahaya. Dan untuk setiap gambar, hitung kecerahan rata-rata relatif terhadap sumbu X dan Y. Ini jelas ditunjukkan pada gambar di bawah ini.

Hasilnya, kami mendapatkan delapan grafik dengan tingkat kecerahan rata-rata.

Selanjutnya, Anda perlu menganalisis grafik ini. Saya memutuskan untuk menggunakan fungsi korelasi dengan membandingkan grafik yang dihasilkan dengan beberapa grafik "sempurna". Grafik ideal dalam kasus ini hanyalah persegi panjang, yang saya dapatkan dengan cara berikut:
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; }
Untuk membandingkan grafik dan, dengan demikian, mendapatkan nilai korelasinya, saya menggunakan fungsi gsl_stats_correlation , implementasi yang saya curi secara jujur ββdari Perpustakaan Ilmiah GNU .
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; }
Selanjutnya, Anda hanya perlu menganalisis nilai korelasi. Saya memutuskan bahwa jika setidaknya satu nilai korelasi kurang dari 0,5, maka telapak tangan tidak terpasang ke sensor atau tidak terpasang dengan baik.
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; }
Juga terlihat dari kode bahwa analisis tingkat kecerahan dilakukan - jika nilainya kurang dari 30, maka kami juga percaya bahwa telapak tangan tidak terpasang.
Tumpukan teknologi yang digunakan
- C / c ++
- Pencipta qt
- QtCharts
- Perpustakaan Ilmiah GNU
Kode sumber
https://github.com/techlinked/PalmDetector.git