Opencv Rect создает только один прямоугольник

В моей попытке реализовать фильтр частиц, я сначала вручную нарисовал прямоугольник (x, y, w, h) вокруг автомобиля на моем изображении (красным цветом), затем я взял 50 частиц и назначил им шум, то есть x = x + шум (0,15) и у = у + шум (0,15).

Затем я хотел перетащить все прямоугольники для каждой частицы в зеленый цвет, но вместо того, чтобы показывать 50 прямоугольников, он показывает только один прямоугольник.

#include<opencv2\core\core.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>

#include<stdio.h>
#include<iostream>
#include<random>

using namespace cv;
using namespace std;const int N = 50;// no of particles

string intToString(int number){

//this function has a number input and string output
std::stringstream ss;
ss << number;
return ss.str();
}int main()
{Mat frame;
frame = imread("f (1).png");
namedWindow("Out");//locating the car manually
Rect car(175, 210, 42, 31);//making a rectangle around the car
rectangle(frame, car, Scalar(0, 0,255), 1, 8, 0);//getting tht height and width of the frame
const int FRAME_HEIGHT = frame.rows;
const int FRAME_WIDTH = frame.cols;//Particle filter initialization

Mat Init = (Mat_<float>(4, 1) << car.x, car.y, 0, 0);//for a gaussian noise distribution
std::default_random_engine generator;
std::normal_distribution<double> distribution(0, 15);//Initializing the particles
std::vector<cv::Mat> particle(N, cv::Mat(4, 1, CV_32F));cout << car.x << " " << car.y << "\n";

for (int i = 0; i < N; i++)
{
particle[i].at<float>(0, 0) = Init.at<float>(0, 0) + distribution(generator);
particle[i].at<float>(1, 0) = Init.at<float>(1, 0) + distribution(generator);
particle[i].at<float>(2, 0) = 0.0;
particle[i].at<float>(3, 0) = 0.0;
cout << particle[i] << "\n";
}

for (int i = 0; i < N; i++)
{
int x = particle[i].at<float>(0, 0);
int y = particle[i].at<float>(1, 0);

rectangle(frame, Rect(x, y, 42, 31), Scalar(0, 255, 0), 1, 8, 0);
}

imshow("Out", frame);waitKey();
return 0;
}

Вывод выглядит так

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

Координаты частицы x y представлены на следующем рисунке. Первая запись о машине, которая была жестко запрограммирована вручную, все остальные — координаты частицы.

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

4

Решение

К сожалению, проблема может быть в векторной инициализации. В соответствии:

 //Initializing the particles
std::vector<cv::Mat> particle(N, cv::Mat(4, 1, CV_32F));

Что вы делаете, это создаете N Mat объектов, инициализированных размером 4 на 1 типа float. Так что, похоже, все в порядке … Подожди! Что если все объекты Mat в векторе имеют одинаковые матричные данные? Все мы знаем, что контейнер Mat имеет заголовок и данные. Данные не копируются, когда заголовки назначаются друг другу или выполняется конструктор копирования. Как и в нашем случае. Что именно давайте представим, как может работать векторный конструктор:

template<class T>
vector::vector (size_type n, const value_type& val = value_type(),
const allocator_type& alloc = allocator_type()) {
// how it can be written? Probably in the following way:
this->resize(n); // allocates using allocator
for(int i=0;i<n;i++)
this->innerBuffer[i] = alloc(val); // runs copy constructor with argument val
// in our case, this is cv::Mat(const cv::Mat &)
}

И если вы думаете о копировании контейнера cv :: Mat, копируется только заголовок. Если вы хотите клонировать сами данные, вы должны указать их напрямую, например, используя метод Mat :: clone (). И векторный конструктор определенно не использует clone (). Таким образом, данные не клонируются, и все объекты Mat совместно используют одни и те же данные, хотя заголовки разные!

Вы можете легко проверить, верно ли это (я был бы удивлен, если бы это было не так): Измените фрагмент кода с:

 for (int i = 0; i < N; i++)
{
particle[i].at<float>(0, 0) = Init.at<float>(0, 0) + distribution(generator);
particle[i].at<float>(1, 0) = Init.at<float>(1, 0) + distribution(generator);
particle[i].at<float>(2, 0) = 0.0;
particle[i].at<float>(3, 0) = 0.0;
cout << particle[i] << "\n"; // it is obvius that HERE particles are different
// beacuse in the next loop run you overwrite them!
}

for (int i = 0; i < N; i++)
{
int x = particle[i].at<float>(0, 0);
int y = particle[i].at<float>(1, 0);

rectangle(frame, Rect(x, y, 42, 31), Scalar(0, 255, 0), 1, 8, 0);
}

в

 for (int i = 0; i < N; i++)
{
particle[i].at<float>(0, 0) = Init.at<float>(0, 0) + distribution(generator);
particle[i].at<float>(1, 0) = Init.at<float>(1, 0) + distribution(generator);
particle[i].at<float>(2, 0) = 0.0;
particle[i].at<float>(3, 0) = 0.0;

}

for (int i = 0; i < N; i++)
{
cout << particle[i] << "\n";

int x = particle[i].at<float>(0, 0);
int y = particle[i].at<float>(1, 0);

rectangle(frame, Rect(x, y, 42, 31), Scalar(0, 255, 0), 1, 8, 0);
}

Я ожидаю, что все частицы одинаковы.

Ссылка: (Вот)

 vector(size_type __n, const value_type& __value,
00199          const allocator_type& __a = allocator_type())
00200       : _Base(__n, __a)
00201       { this->_M_impl._M_finish = std::uninitialized_fill_n(this->
00202                                 _M_impl._M_start,
00203                                 __n, __value); }
00204
4

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


По вопросам рекламы [email protected]