我用 code::blocks 编写了一个小型 C++ 控制台应用程序,它从 CSV 文件加载值数组,对值执行特殊的“反转”随机抖动,并将结果导出为 PBM 文件(位图)。
最终 PBM 图片上黑色像素的密度取决于 3 个自变量:“白色反射率”、“黑色反射率”和 CSV 值。
我使用 CSV 文件的原因是因为我不知道如何将 TIFF 文件直接加载到我的脚本中。我的文件“wall.csv”的值是由一个 python 脚本生成的,该脚本可以转换 csv 中的任何 tiff 文件......
您能否检查我的代码并建议加载 TIFF 并自动检测图像大小(以像素为单位)的解决方案?变量colo
和lines
定义包含在 CSV 中的 ASCII 数据的图像大小......并且图像值被加载到vector <float> CSV
您将使用什么库来加载 tiff?
谢谢!
代码:
#include <deque>
#include <cmath>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <random>
#include <cstdlib>
using namespace std;
deque <float> CSV; // CSV input values, "PHOTOMETRY"
deque <float> RND; // will contain random values from 0.0 to 1.0
int colo = 0; // variables inputed
int lines = 0; // lines
float YBK = 0; // Reflectance White
float YW = 0; // Reflectance Black
float Lmax = 0; // variables to be computed
float Lmin = 10000000; // arbitrarily high value
float NBK = 0; // will contain a normalized Black value
float NW = 1; // normalized white value
float CRATIO = 0; // Black to White dynamic ratio
float LRATIO = 0; // Lowest to Highest pixel value dynamic ratio
float Z = 0; // processing variables
float X = 0;
float aBK = 0; // computed density of black at each pixel
float vRND = 0; // random value container
float IO = 0;
int main(){
cout << "please put a file named wall.csv" << endl << "in the same forler as this executable" << endl << endl;
cout << "how many:" << endl << "columns does the CSV has?" << endl;
cin >> colo;
cout << "lines does the CSV has?" << endl;
cin >> lines;
cout << "reflectance of the WHITE (CIE Y)?" << endl;
cin >> YW;
cout << "reflectance of the BLACK (CIE Y)?" << endl;
cin >> YBK;
NBK = YBK / YW; // normalized BK
CRATIO = NW / NBK; // correction Ratio
int C = lines * colo; // cells
cout << endl << " there are: " << colo << " columns";
cout << endl << " and : " << lines << " lines " ;
cout << endl << " that makes " << C << " cells " << endl;
cout << endl << " correction ratio is: " << CRATIO << endl << endl;
///_____ IMPORT THE PHOTOMETRIC DATA
cout << "...importing the photometric data" << endl;
float x = 0; // a variable that will contain a value from the file
ifstream ifs ("wall.csv");
char dummy;
for (int i = 0; i < lines; ++i){
for (int i = 0; i < colo; ++i){
ifs >> x;
if (x > Lmax) {
Lmax = x; // determines the highest pixel value
}
if (x < Lmin) {
Lmin = x; // determines the lowest pixel value
}
CSV.push_back(x);
// So the dummy won't eat digits
if (i < (colo - 1))
ifs >> dummy;
}}
ifstream ifs_close();
LRATIO = Lmax / Lmin;
cout << "...photometric data imported" << endl;
cout << endl << " maximum Luminance is: " << Lmax;
cout << endl << " minimum Luminance is: " << Lmin << endl;
cout << endl << "...luminance ratio is: " << LRATIO;
if (LRATIO > CRATIO) {
cout << endl << "...luminance ratio is: " << LRATIO;
cout << endl << "...this is too high, ending..." << '\a';
return(0);
}
cout << endl << "...luminance can be corrected :)" << endl;
///______ CREATE RANDOM VALUES BETWEEN 0 & 1
std::default_random_engine generator;
std::uniform_real_distribution <double> distribution(0.0,1.0);
for (int i=0; i<C; ++i) {
double number = distribution(generator);
RND.push_back(number);
}
cout << endl << "...random values created" << endl;
///_______ process & export to PBM
ofstream output_file("./wall.pbm");
output_file << "P1" << "\n" << colo << " " << lines << "\n"; /// PBM HEADER
cout << endl << "...file header written" << endl;
cout << endl << "...computing";
int CELLS = C; // copy the amount of cells
int LINEW = colo;
int PERCENT = 100;
while (CELLS > 0) {
while (LINEW > 0) {
Z = Lmin/CSV.front(); /// processing calculus
X = (NBK - Z)/(NBK - NW);
aBK = (1 - X);
vRND = RND.front();
if (aBK > (vRND)) {
IO = 1;
}
else {
IO = 0;
}
LINEW = LINEW - 1;
CELLS = CELLS - 1;
PERCENT = PERCENT - CELLS / C;
output_file << IO << "\n";
//cout << ERR << " "; /// fancy...
CSV.erase(CSV.begin());
RND.erase(RND.begin());
}
LINEW = colo;
}
cout << endl << "...computing done" << endl;
cout << "...file written";
output_file.close();
return(0);
}