Как-то ко мне в руки попало тестовое задание.
Академический интерес взял верх и я решил заняться этой проблемой.
Мое решение не претендует на оптимальность или правильность.
Мне просто было интересно решить эту проблему.
Исходные данные
Суть задачи — написать программу, которая по снимкам со сканера вен ладони определяет, прикреплена ли ладонь к сканеру.Исходные данные — это несколько изображений с заранее известным результатом.
Результат
Программа с графическим интерфейсом с возможностью выбора изображения из списка.После выбора изображение анализируется и после анализа результат отображается в виде надписи.
Хороший или Плохой .
Алгоритм
Алгоритм анализа изображения достаточно прост. Сначала я создал класс Анализатор изображений со следующим интерфейсомВнутри этого класса я решил условно разделить изображение на 4 части для каждого источника света.class ImageAnalyser { public: ImageAnalyser(); explicit ImageAnalyser(const QImage&); bool analyze(const QImage&); bool analyze(); std::vector<std::vector<int>> data(); virtual ~ImageAnalyser(); };
И для каждого изображения посчитайте среднюю яркость относительно осей Икс И ты .
Это наглядно продемонстрировано на изображении ниже.
В результате мы получаем восемь графиков со средним уровнем яркости.
Далее вам необходимо проанализировать эти графики.
Я решил использовать корреляционную функцию, сравнив полученные графики с каким-то «идеальным» графиком.
Идеальный график в данном случае — это просто прямоугольник, который я получаю следующим образом: 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, то мы также предполагаем, что ладонь не применяется.
Стек используемых технологий
- С/С++
- Создатель Qt
- QtCharts
- Научная библиотека ГНУ
Источники
https://github.com/techlinked/PalmDetector.git Теги: #биометрия #программирование #C++ #Обработка изображений #анализ изображений #Qt #qtcreator #биометрические сканеры-
Я Mac: Половина Youtube
19 Oct, 24 -
Почему I2Istudy Не Сотрудничал С Фрии
19 Oct, 24