所给rgb文件是按照b,g,r顺序排列的且去掉了包含文件属性的文件头,文件分辨率为 256 × 256 256\times256 256×256。
该段代码可以实现如下功能:
由于c++作图不方便,于是图表均为excel完成。
#include
#include
#include
#include
using namespace std;
const char* inPath = "D:\\CLionProjects\\algorithm\\cmake-build-debug-mingw\\down.rgb";
const char* outPath = "D:\\CLionProjects\\algorithm\\cmake-build-debug-mingw\\data.csv";
const char* outFile = "D:\\CLionProjects\\algorithm\\cmake-build-debug-mingw\\data.cif";
//这里建议使用绝对路径
//使用相对路径时需要放到IDE默认的路径或手动设置
int num[6][256], len = 0;
double entropy[6];
vector< unsigned char > YUV[3];
int main()
{
//打开rgb文件
ifstream in(inPath, ios::binary);
if (!in.is_open()) { cout << inPath << " can not be opened!" << endl; return 0; }
while ( !in.eof())
{
unsigned char r, g, b, y, u, v, pos = 0;
//读入r,g,b的值
for (auto i : { &b,&g,&r }) *i = in.get();
//计算Y,U,V分量
y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
//统计数值出现次数
for (auto i : { r,g,b,y,u,v }) num[pos++][i] ++;
pos = 0; len++;
//存储Y,U,V的值
for (auto i : { y,u,v }) YUV[pos++].push_back(i);
}
in.close();
//创建表格
ofstream out(outPath, ios::binary);
if (!out.is_open()) { cout << outPath <<" can not be opened!" << endl; return 0; }
//输出表格内容
out << "Value,R,G,B,Y,U,V" << endl;
for (int j = 0; j < 256; ++j)
{
out << j << ",";
for (int i = 0; i < 6; ++i)
{
double p = 1.0 * num[i][j] / len;
out << p << (i == 5 ? "\n" : ",");
if (p != 0) entropy[i] -= p * log2f(p);
}
}
out << endl << " ,R,G,B,Y,U,V" << endl << "entropy,";
for (int i = 0; i < 6; ++i) out << entropy[i] << (i == 5 ? "\n" : ",");;
out.close();
//创建CIF文件
out.open(outFile, ios::binary);
if (!out.is_open()) { cout << outFile << " can not be opened!" << endl; return 0; }
//输出内容
for (auto& i : YUV) for (auto j : i) out << j;
out.close();
}
生成的表格如下:
各个分量的熵:
R,G,B和Y,U,V取值的频率图:
可见YUV格式中各个分量出现的比较集中。