I am trying to extract a histogram matrix for every 5 frames in a video for further processing. The process is as follow:

  1. From 1st to 5th frame:
  2. Convert in HSV and generate a histogram for each channel.
  3. Save histogram of three channels into a vector of Mat
  4. Append the vector of Mat of each frame into each row a new Mat
  5. Repeat step 1 to step 4 to generate the feature matrix, process the Mat feature matrix, then remove data of 1st frame in the Mat, and repeat the process for the next 5 frames, loop until the end of the video.

The output of step 5 is the feature matrix over time.

I step 4, I want generate a new Mat that stores the histograms of every frame in each row. In the matrix, number of rows = number_of_frames, number of columns = 16+4+4 (number of bins).

I created a function for step 4 (formatHistogramforSVD) but the data output of step 3 & 4 are different. Only the 1st element of the vector is passed correctly into Mat matrix.

int main ()
{
string path = "";
Mat image;

VideoCapture capture(path);
if (!capture.isOpened())     
{
cout << "could not open the VideoCapture !" << endl;
return -1;
}

for (int i = 0; i < 5; i++)
{
capture >> image;
    // generate histogram and save into a vector of Mat
vector<Mat> histogramI = calculate_histogram(image); 
    // Reshape and stack histogram into a rowMatrix
Mat matrix_histograms = formatHistogramforSVD(histogramI);

    cout << matrix_histograms << endl;
}
}
vector<Mat> calculate_histogram(Mat image)
{
cvtColor(image, hsvImage, COLOR_BGR2HSV);
vector<Mat> bgrPlanes;
split(hsvImage, bgrPlanes);
Mat hHist, sHist, vHist;
    int hMax = 16, svMax = 4; 
calcHist(&bgrPlanes[0], 1, 0, Mat(), hHist, 1, &hMax, &hRange); 
calcHist(&bgrPlanes[1], 1, 0, Mat(), sHist, 1, &svMax, &svRange);
calcHist(&bgrPlanes[2], 1, 0, Mat(), vHist, 1, &svMax, &svRange);

vector<Mat> histogramI = { hHist, sHist, vHist };
return histogramI;
}

Mat formatHistogramforSVD(const vector<Mat> &data)
{
Mat dst(static_cast<int>(data.size()), data[0].rows*data[0].cols, CV_32F);
for (unsigned int i = 0; i < data.size(); i++)
{
    Mat image_row = data[i].clone().reshape(1, 1);
    Mat row_i = dst.row(i);
    image_row.convertTo(row_i, CV_32F);
}
return dst;
}

output of my code

enter image description here

THE DESIRED OUTPUT FOR EACH ROW IN THE MAT [1966, 10, 19, 43, 28, 36, 94, 36, 50, 56, 148, 84, 130, 204, 214, 522,1829, 746, 933, 315]

How can I generate data correctly for the MAT after step 4?

0 Answers