Как обнаружить объект на изображении, используя дескрипторы HOG? - PullRequest
0 голосов
/ 28 марта 2019

При отслеживании объекта я хочу иметь возможность повторно обнаружить его после окклюзии.

В OpenCV 3.4.5 (C ++) я пробовал сопоставление с шаблоном и оптическую сегментацию потока.Но теперь я хотел бы реализовать более надежный алгоритм с использованием дескриптора HOG.

Я сделал небольшой пример, чтобы показать проблему.Вот мои 2 изображения:

enter image description here автомобиль, который я хочу обнаружить

enter image description here изображение, в котором я ищу

PS: я не хочу обучать SVM, так как хочу обнаружить уникальный объект только в нескольких кадрах.

Мой код:

#include <opencv2/core/utility.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect.hpp>

#include <iostream>
#include <vector>

using namespace std;
using namespace cv;

int main(int argc, char** argv){

        //load images
        Mat lastSeenObject=imread("lastSeenObject.png",1); //21x39
        Mat patch=imread("patch.png",1); //150x150

        //params
        Size cellSize(8,8);
        int nbins= 9;
        Size blockSize(2,2);

        //my variables
        vector<float>templ_descriptor;
        vector<float>p_descriptor;
        Mat templ_gray,p_gray,iMatches;
        vector<DMatch> matches;

        //convert to gray
        cvtColor(lastSeenObject,templ_gray,CV_BGR2GRAY);
        cvtColor(patch,p_gray,CV_BGR2GRAY);

        //create hog object
        HOGDescriptor hog(Size(templ_gray.cols/cellSize.width*cellSize.width,templ_gray.rows/cellSize.height*cellSize.height),
                Size(blockSize.height*cellSize.height,blockSize.width*cellSize.width),
                Size(cellSize.height,cellSize.width),
                cellSize,
                nbins);
        // gives --> winSize [32 x 16],  blockSize [16 x 16],  blockStride [8 x 8],  cellSize [8 x 8]

        //compute the descriptor of the car
        hog.compute(templ_gray,templ_descriptor, Size(cellSize.height,cellSize.width), Size( 0, 0 ));
        //templ_descriptor.size() = 108, containing floats between 0 and 1

        //compute the descriptor of the patch
        hog.compute(p_gray,p_descriptor, Size(cellSize.height,cellSize.width), Size( 0, 0 ));
        //p_descriptor.size() = 27540, containing floats between 0 and 1

        //compare the descriptors
        double err=0;
        double min_err = -1;
        int idx=-1;
        for (unsigned int i =0;i<p_descriptor.size();i++)
        {
            if(i%templ_descriptor.size()==0 && i!=0) // iterate the computation of error over the templ_descriptor size
            {
                if(err<min_err || min_err ==-1)
                {
                    min_err = err;
                    idx = i-nbins;
                }
                err = 0;
            }
            //euclidean error distance accumulator between each component of the histogram
            err += abs(p_descriptor[i] - templ_descriptor[i%templ_descriptor.size()]);
        }

        // we get idx = 11655 and err = 5.34021

        //convert vector idx in x,y coordonates in the patch
        int row= static_cast<int>(idx/patch.cols);
        int col = idx%patch.cols;

        //show the result
        Rect2f found_object(col,row,hog.winSize.width,hog.winSize.height); // [32 x 16 from (105, 77)]
        rectangle(patch,found_object,Scalar(0,0,255));
        imshow("result",patch);
        waitKey(500000);

        return 1;
}

Мой результат

enter image description here

Конечно, ожидаемый результат - наличие ограничительной рамки на транспортном средстве.

Мои вопросы

1 / Как структурирован дескриптор, возвращаемый функцией compute?

Я предполагаю, что имеется 9 (nBins) чисел, описывающихa cellSize, но я не понимаю, почему у меня есть 108/9 = 12 ячеек в templ_descriptor, в то время как winSize составляет 16x32, а cellSize 8x8.

2 / Как извлечь координаты пикселей winSize изp_descriptor, что лучше всего соответствует templ_descriptor?

3 / Есть ли у вас какие-либо другие предложения по решению моей проблемы переопределения моей цели после небольших окклюзий?

Helpful links

Документация OpenCV 3.4.5 по дескриптору HOG

Статья LearnOpenCV по HOG

1 Ответ

1 голос
/ 28 марта 2019

Попробуйте использовать SIFT .Чтобы использовать SIFT в opencv3, вам нужно собрать opencv с contrib ON.

Если вы все еще хотите попробовать, работает ли HOG.Попробуйте вычислить расстояние между двумя векторами - дескриптором изображения транспортного средства и каждым дескриптором большего изображения.Размеры вектора должны быть одинаковыми, если вы установите blockSize = (vehicle image size).

Недостаток HOG - слабая устойчивость к вращению.SIFT заставляет объекты вращаться на любой угол.Тем не менее, SIFT больше относится к узорам деталей на объектах, поэтому он может быть более рискованным, если разрешение изображения довольно мало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...