БЫСТРЫЙ Алгоритм: Обнаружение без углов в прямоугольных формах

Я пытаюсь реализовать свой собственный алгоритм FAST на c ++, следуя учебному пособию по OpenCV. Как алгоритм говорит :

Пиксель p является углом, если существует множество из n смежных
пикселей в круге (из 16 пикселей), которые все ярче, чем I_p +
т, или все темнее, чем I_p — т. (Показано в виде белых штриховых линий на
образ). N был выбран, чтобы быть 12.

Высокоскоростной тест был предложен, чтобы исключить большое количество
не-углы. Этот тест проверяет только четыре пикселя в 1, 9, 5 и 13
(Первые 1 и 9 проверяются, если они слишком яркие или темные. Если так,
затем проверяет 5 и 13). Если р — угол, то по крайней мере три из них
все должны быть ярче, чем I_p + t, или темнее, чем I_p — t. Если ни
из этого случая, тогда р не может быть углом. Полный сегментный тест
критерий может быть применен к прошедшим кандидатам путем изучения
все пиксели в круге. Этот детектор сам по себе показывает высокий
спектакль

Я сравнил свой вывод FAST с выводом FAST OpenCV с порогом = 100. Я понял, что мой не может обнаружить все углы:
введите описание изображения здесь

Когда я уменьшаю n до 0 (хотя n должно быть> 12 для получения оптимальных результатов), я получаю тот же результат (только) с этим типом теста изображения, но все же он не обнаруживает углы прямоугольных форм в целом:

введите описание изображения здесь

Вот мой полный код:

#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <iostream>
#include <opencv2/features2d/features2d.hpp>

using namespace std;
using namespace cv;

#define THRESHOLD 100/*
** Compares intensity of pixels 1,5,9,13 of the circle surrounding a pixel at (i,j) of an image with its intensity ip.
** If 3 out of 4 satisfy the threshold FAST constraints : bright (i>ip+t) & dark (i<ip-t),
** the pixel at (i,j) is considered a possible key point
*/
bool couldBeKeyPoint(Mat imageIn, int i, int j, int threshold) {
uchar ip   = imageIn.at<unsigned char>(i, j); //intensity of the potential key point
uchar ip9  = imageIn.at<unsigned char>(i, j - 3); //intensity of pixel 1 of the surrounding circle
uchar ip1  = imageIn.at<unsigned char>(i, j + 3); //intensity of pixel 9 of the surrounding circle
uchar ip5  = imageIn.at<unsigned char>(i + 3, j); //intensity of pixel 5 of the surrounding circle
uchar ip13 = imageIn.at<unsigned char>(i - 3, j); //intensity of pixel 13 of the surrounding circle

//checking FAST bright constraints on these 4 surrounding pixels
bool b1 = (ip1 >= ip +  threshold);
bool b9 = (ip9 >= ip +  threshold);
bool b5 = (ip5 >= ip +  threshold);
bool b13 = (ip13 >= ip +  threshold);

//cout << b1+b9+b5+b13 ;
//at least three of these must all be brighter than I_p + t.
if (b1+b9+b5+b13 >=3)
return true;

bool d1 = (ip1 <= ip - threshold);
bool d9 = (ip9 <= ip -  threshold);
bool d5 = (ip5 <= ip - threshold);
bool d13 = (ip13 <= ip -  threshold);
//cout << d1+d9+d5+d13 << "\n" ;
//at least three of these must all be darker than I_p − t.
if (d1+d9+d5+d13 >=3)
return true;

return false;
}

bool isKeyPoint(Mat imageIn, int i, int j, int threshold, int numberPixelsToCheck){
cout << "iskeypoint";
vector<unsigned char> pixelSurroundings;

pixelSurroundings.push_back(imageIn.at<unsigned char>(i, j));//the potential key point
pixelSurroundings.push_back(imageIn.at<unsigned char>(i, j + 3));//pixel 1
pixelSurroundings.push_back(imageIn.at<unsigned char>(i + 1, j + 3 3));//pixel 2
pixelSurroundings.push_back(imageIn.at<unsigned char>(i + 2, j + 2));//pixel 3
pixelSurroundings.push_back(imageIn.at<unsigned char>(i + 3, j + 1));//pixel 4
pixelSurroundings.push_back(imageIn.at<unsigned char>(i + 3, j));//pixel 5
pixelSurroundings.push_back(imageIn.at<unsigned char>(i + 3, j - 1));//pixel 6
pixelSurroundings.push_back(imageIn.at<unsigned char>(i + 2, j - 2));//pixel 7
pixelSurroundings.push_back(imageIn.at<unsigned char>(i + 1, j - 3));//pixel 8
pixelSurroundings.push_back(imageIn.at<unsigned char>(i, j - 3));//pixel 9
pixelSurroundings.push_back(imageIn.at<unsigned char>(i - 1, j - 3));//pixel 10
pixelSurroundings.push_back(imageIn.at<unsigned char>(i - 2, j - 2));//pixel 11
pixelSurroundings.push_back(imageIn.at<unsigned char>(i - 3, j - 1));//pixel 12
pixelSurroundings.push_back(imageIn.at<unsigned char>(i - 3, j));//pixel 13
pixelSurroundings.push_back(imageIn.at<unsigned char>(i - 3, j + 1));//pixel 14
pixelSurroundings.push_back(imageIn.at<unsigned char>(i - 2, j + 2));//pixel 15
pixelSurroundings.push_back(imageIn.at<unsigned char>(i - 1, j + 3));//pixel 16

if (numberPixelsToCheck > 16){
numberPixelsToCheck = 12; //The author have used N=12 in the first version of the algorithm
cout <<  "Error number of surrounding pixels to check should not exceed 16! Value 12 was used instead. " << std::endl ;
}

unsigned char ip = pixelSurroundings[0];
int  brightScore = 0;
int  darkScore = 0;
bool d = false,e=false;
for(int j=1;j<pixelSurroundings.size();j++){
unsigned char i = pixelSurroundings[j];
d = (i >= ip + (unsigned char ) threshold);
e = (i <= ip - (unsigned char ) threshold);

brightScore += d;
darkScore +=  e;
}
cout << darkScore << " DARKSCORE \n";
cout << brightScore << " BRIGHTSCORE \n";
if (darkScore >= numberPixelsToCheck || brightScore >= numberPixelsToCheck){
//cout << darkScore << " DARKSCORE \n";
//cout << brightScore << " BRIGHTSCORE \n";
return true; //the pixel is a key point
}

return false;
}

//renvoit un ensemble de détections
//inputarray image
vector<KeyPoint> FAST(Mat imageIn, vector<KeyPoint> keypoints, int threshold){
if(!imageIn.data )                              // Check for invalid input
{
cout <<  "Could not open or find the image" << std::endl ;
//return {};
}
keypoints.clear();
int i, j, count =0;
for (i = 3; i < imageIn.rows - 3; i++)
{
for (j = 3; j < imageIn.cols - 3; j++)
{
if (couldBeKeyPoint(imageIn, i, j, threshold)){
if (isKeyPoint(imageIn, i, j, threshold, 0)){
keypoints.push_back(KeyPoint(j, i ,1));
count++;
cout << "keypoint found at " << i << " " << j << "\n";
}
}
}
}
cout << "NUMBER OF KEYPOINTS :" << keypoints.size() << "\n";
return keypoints;
}int main(int argc, char** argv){
vector<KeyPoint> keypointsMyFast;
vector<KeyPoint> keypointsOpenCvFast;
Mat src, destMyFast, destOpenCvFast;
//src= imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
//src= imread(argv[1], CV_8UC3);
src= imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
imshow( "ORGINAL",src);
waitKey(1);

keypointsMyFast = FAST(src, keypointsMyFast,THRESHOLD);
drawKeypoints(src, keypointsMyFast, destMyFast, Scalar(255,0,0));
imshow( "MYFAST",destMyFast);
waitKey(1);
FAST(src,keypointsOpenCvFast,THRESHOLD,false);
cout << "NUMBER OF open cv KEYPOINTS :" << keypointsOpenCvFast.size() << "\n";
drawKeypoints(src, keypointsOpenCvFast, destOpenCvFast, Scalar(255,0,0));
imshow( "Display window",destOpenCvFast);
waitKey(0);}

Любая идея о том, что может заставить алгоритм не обнаруживать углы в прямоугольниках?
Особенно: как правильно загрузить изображение, используя imread? (Изменение второго аргумента дает разные результаты)

огромное спасибо

0

Решение

Проблема возникает в первоначальной функции canBeKeyPoint. Эта функция проверяет местоположение ключевой точки-кандидата в верхнем, нижнем, левом и правом положениях и возвращает значение true, если центральная точка светлее / темнее, чем 3 из окружающих точек.

Это предположение не выполняется для прямоугольника или прямоугольника, поскольку край квадрата / прямоугольника никогда не может соответствовать условиям. Вам нужно ослабить состояние функции, уменьшив количество окружающей точки до 2.

3

Другие решения

Других решений пока нет …