БЫСТРЫЙ Алгоритм: Обнаружение без углов в прямоугольных формах - PullRequest
0 голосов
/ 16 декабря 2018

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

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

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

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

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

enter image description here

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

#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?(Изменение второго аргумента дает разные результаты)

Большое вам спасибо

1 Ответ

0 голосов
/ 16 декабря 2018

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

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

...