图像处理-将矩阵中的16位写入文本文件,并用C++以不同的方式读取
image processing - Writing 16 bits from matrix to a text file, reading them back in differently in C++
我有一个无符号16的矩阵,我正在使用将其写入文本文件
void output() {
ofstream myfile;
myfile.open("output.raw", ios::out | ios::binary);
for(int i=0; i< 100; i++) {
for(int j=0; j < 100; j++) {
myfile.write((char*)&r2[i][j], sizeof(uint16_t));
}
}
}
由于这是一个".raw"图像文件,我认为每个uint16都应该连续写入该文件,而不会有任何中断(如果我错了,请纠正我)。
当我在中读取数据时,数组中包含的值与进入文本文件时的值不同。我正在用读取数据
for(int i=0; i<NUM_COLS; i++) {
for(int j=0; j<NUM_ROWS; j++) {
fread(&q1[j][i], sizeof(uint16_t), 1, fp);
}
}
有人猜测为什么会发生这种情况吗?
不能逐位写入浮点数据并将其读回int。在写入浮点数据之前,必须将浮点转换为整数数据类型。浮点数字有一种完全不同的整数二进制表示形式:IEEE_754
for(int i=0; i< 100; i++) {
for(int j=0; j < 100; j++) {
uint16_t val = (uint16_t)r2[i][j];
myfile.write((char*)&val , sizeof(uint16_t));
}
}
此外,您以错误的顺序读回值:
fread(&q1[j][i], sizeof(uint16_t), 1, fp);
应该是
fread(&q1[i][j], sizeof(uint16_t), 1, fp); // i and j interchanged
为了好玩,我编写了这些通用助手来将任意二维数组写入二进制流:
namespace arraystream
{
template <class T, size_t M> std::istream& operator>>(std::istream& is, const T (&t)[M])
{ return is.read ((char*) t, M*sizeof(T)); }
template <class T, size_t M> std::ostream& operator<<(std::ostream& os, const T (&t)[M])
{ return os.write((char*) t, M*sizeof(T)); }
template <class T, size_t N, size_t M> std::istream& operator>>(std::istream& is, const T (&tt)[N][M])
{ for (size_t i=0; i<N; i++) is >> tt[i]; return is; }
template <class T, size_t N, size_t M> std::ostream& operator<<(std::ostream& os, const T (&tt)[N][M])
{ for (size_t i=0; i<N; i++) os << tt[i]; return os; }
}
你可以在你的代码中这样使用它们:
char c [23] [5];
float f [7] [100];
uint16_t r2[100][100]; // yes that too
std::ofstream ofs("output.raw", std::ios::binary || std::ios::out);
ofs << c << f << r2;
ofs.flush();
ofs.close();
////
std::ifstream ifs("output.raw", std::ios::binary || std::ios::in);
ifs >> c >> f >> r2;
ifs.close();
这里唯一的小缺点是,如果要在命名空间std中声明这些(或一直在use
中声明它们),编译器也会尝试使用这些重载来编写std::cout << "hello world"
(即char[12]
)。我选择在需要的地方明确地使用use
和arraystream
命名空间,请参阅下面的完整示例。
这里有一个完整的可编译示例,通过校验和哈希显示读取回的数据确实是相同的Boost不需要即可使用这些助手。我使用boost::random来获取一组随机数据,boost::hash来做校验和。您可以使用任何随机生成器,也可以使用外部校验和工具。
事不宜迟:
#include <fstream>
#include <boost/random.hpp>
#include <boost/functional/hash.hpp>
namespace arraystream
{
template <class T, size_t M> std::istream& operator>>(std::istream& is, const T (&t)[M]) { return is.read ((char*) t, M*sizeof(T)); }
template <class T, size_t M> std::ostream& operator<<(std::ostream& os, const T (&t)[M]) { return os.write((char*) t, M*sizeof(T)); }
template <class T, size_t N, size_t M> std::istream& operator>>(std::istream& is, const T (&tt)[N][M])
{ for (size_t i=0; i<N; i++) is >> tt[i]; return is; }
template <class T, size_t N, size_t M> std::ostream& operator<<(std::ostream& os, const T (&tt)[N][M])
{ for (size_t i=0; i<N; i++) os << tt[i]; return os; }
}
template <class T, size_t N, size_t M>
size_t hash(const T (&aa)[N][M])
{
size_t seed = 0;
for (size_t i=0; i<N; i++)
boost::hash_combine(seed, boost::hash_range(aa[i], aa[i]+M));
return seed;
}
int main()
{
uint16_t data[100][100];
{
// make some (deterministic noise)
boost::mt19937 rand(0);
for (int i=0; i<100; i++) for (int j=0; j<100; j++) data[i][j] = rand();
}
{
// write a file
std::ofstream ofs;
ofs.open("output.raw", std::ios::out | std::ios::binary);
using namespace arraystream;
ofs << data;
ofs.flush();
ofs.close();
}
uint16_t clone[100][100];
{
// read a file
std::ifstream ifs;
ifs.open("output.raw", std::ios::in | std::ios::binary);
using namespace arraystream;
ifs >> clone;
ifs.close();
}
std::cout << "data: " << hash(data) << std::endl;
std::cout << "clone: " << hash(clone) << std::endl;
return 0;
}
相关文章:
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 我想生成许多矩阵并用随机数填充它
- 获取带有字符 X 的输入 X/X/etc 并用斜杠 / 分隔它
- 如何创建一个新的二进制文件并用常量值填充它?
- C++初始化并用变量填充 2D 数组
- 如何将矢量大小扩展一个元素并用变量填充它
- 删除两个相邻的元素并用矢量中的单个元素替换它们
- 如何在内存位置取消指针,并用值启动它
- 函数读取最大和min int值,并用文本字符串返回
- 为什么GCC违反了调用ABS功能的代码,并用简短的参数进行功能
- 覆盖方法并用shared_ptr调用它们的奇怪行为
- 如何更改数组的大小并用自动化元素填充它
- 使用包含每个重复数量的列表生成重复,上升整数的顺序,并用推力
- 我试图释放数据的某些部分,并用特定的整数值标记其休息,以表明它不是有效的指针.(不是数组)
- RSA用加密 编码,并用C#rsacryptoserviceProvider解码
- Cython包裹CPP结构并用参数构成结构的阵列
- 用 c++ 编写二进制文件并用 python 读取
- 序列化结构以归档,并用字符串再次对其进行启用
- 什么不能接受字符串向量并用 offest 和 assigmnet 运算符替换任何字符串的字符?
- 有什么方法可以制作一个程序,随机选择10-20个字符串并用C++向用户显示