不知何故,我落入了测试任务之手。 学术兴趣盛行,我决定参加这项任务。 我的解决方案并不声称是最佳和正确的。 我只是想解决这个问题。
源数据
任务的实质是编写一个程序,该程序通过来自手掌静脉扫描仪的图像确定手掌是否已连接到扫描仪。
初始数据-具有已知结果的几幅图像。

结果
该程序带有图形界面,可以从列表中选择图像。 选择后,将对图像进行分析,并在分析后以题为“ 好”或“ 不好”的形式显示结果。


演算法
图像分析算法非常简单。 首先,我使用以下接口创建了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函数,该函数的实现我确实是从GNU Scientific Library中偷走的。
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 ++
- Qt创作者
- Qt图表
- GNU科学图书馆
源代码
https://github.com/techlinked/PalmDetector.git