【发布时间】:2018-07-10 19:25:21
【问题描述】:
我是 OpenCV 的新手。我正在开发 Visual Studio 2017 并使用插件 Image Watch 来查看 openCV 的 Mat 文件。
我做了什么:
我必须读取一个二进制文件才能在双精度数组中获取 1000 个图像(256*320 像素 uint16 所以 2 个八位字节)。在此之后,我想通过 Image Watch 查看我的数据,以确保一切正常。因此,我将第一张图像转换为 8 位的 uchar 以将其可视化。我添加我的代码(大部分不看,直接到最后):
#include "stdafx.h"
#include <iostream>
#include "stdio.h"
#include <fstream>
#include <stdint.h>
#include "windows.h"
#include <opencv2/core/core.hpp> // cv::Mat
#include <math.h>
#include <vector>
using namespace std;
using namespace cv;
template<class T>
T my_ntoh_little(unsigned char* buf) {
const auto s = sizeof(T);
T value = 0;
for (unsigned i = 0; i < s; i++)
value |= buf[i] << CHAR_BIT * i;
return value;
}
int main()
{
ifstream is("Filename", ifstream::binary);
if (is) {
// Reading size of the file and initialising variables
is.seekg(0, is.end);
int length = is.tellg();
int main_header_size = 3000;
int frame_header_size = 1000;
int width = 320, height = 256, count_frames = 1000;
int buffer_image = width * height * 2;
unsigned char *data_char = new unsigned char[length]; // Variable which will contains all the data
// Initializing 3D array for stocking all images
double ***data;
data = new double**[count_frames];
for (unsigned i = 0; i < count_frames; i++) {
data[i] = new double*[height];
for (unsigned j = 0; j < height; j++)
data[i][j] = new double[width];
}
// Reading the file once
is.seekg(0, is.beg);
is.read(reinterpret_cast<char*>(data_char), length);
// Convert pixel by pixel uchar into uint16 (using pointer on data_char)
int indice, minid = 65536.0, maxid = 0.0;
for (unsigned count = 0; count < count_frames; count++) {
// Initialize pointer address
indice = main_header_size + count * (frame_header_size + buffer_image) + frame_header_size;
for (unsigned i = 0; i < height; i++) {
for (unsigned j = 0; j < width; j++) {
data[count][i][j] = my_ntoh_little<uint16_t>(data_char + indice);
// Search for min/max for normalize after
if (data[count][i][j] < minid and count == 0)
minid = data[count][i][j];
if (data[count][i][j] > maxid and count == 0)
maxid = data[count][i][j];
// Updating pointer to next pixel
indice += 2;
}
}
}
// Get back first image, normalize between 0-255, cast into uchar to the future Mat object
uchar *dataImRGB = new uchar[width * height * 3];
int image_display = 900;
int pixel_norm;
for (unsigned i = 0; i < height; i++) {
for (unsigned j = 0; j < width; j++) {
pixel_norm = round((data[image_display][i][j] - double(minid)) / double(maxid - minid) * 255);
dataImRGB[i * 320 * 3 + 3 * j] = static_cast<uchar>(pixel_norm);
dataImRGB[i * 320 * 3 + 3 * j + 1] = static_cast<uchar>(pixel_norm);
dataImRGB[i * 320 * 3 + 3 * j + 2] = static_cast<uchar>(pixel_norm);
}
}
// Create Mat object (it is imageRGB8 I can see on Image watch)
Mat imageRGB8 = Mat(width, height, CV_8UC3, dataImRGB);
// Creating a list of Map and add first Mat
vector<Mat> listImages;
listImages.push_back(imageRGB8);
// -----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------
// Future : directly keep the uchar read in the original file and import it on a Mat object
// But how to get the pixel at (0,0) of the first Mat on the vector ?
// -----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------
// De-Allocate memory to prevent memory leak
for (int i = 0; i < count_frames; ++i) {
for (int j = 0; j < height; ++j)
delete[] data[i][j];
delete[] data[i];
}
delete[] data;
}
return 0;
}
我被困在哪里:
我不知道如何使用这个向量,如何操作数据。例如,如果我想做所有图像的平均值,那么向量中所有 Mat 对象的平均值,该怎么做?或者只是如何获得向量中第三个图像的第一个像素?这些示例旨在向我解释使用此类数据进行切片,因为我知道它如何与 double 向量一起使用,但不适用于 openCv 对象。
提前感谢您的任何帮助/建议。
【问题讨论】: