Skip to content

Commit e31e323

Browse files
author
Erika
committed
added tile and strip functions for read the tiff files
1 parent 4a532de commit e31e323

File tree

3 files changed

+203
-80
lines changed

3 files changed

+203
-80
lines changed

depthmap/depthmap.cpp

+189-75
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,18 @@
1010

1111
using namespace std;
1212

13-
bool Depthmap::load(const char *tiff) {
13+
14+
bool Depthmap::loadTiff(const char *tiff, vector<float> &values, uint32_t &w, uint32_t &h) {
1415
TIFF* inTiff = TIFFOpen(tiff, "r");
1516

1617
if (!inTiff) {
1718
cerr << "Could not open input TIFF file." << endl;
1819
return false;
1920
}
2021

21-
// Check if the TIFF is tiled
22-
uint32_t tileWidth, tileLength;
23-
if (!TIFFGetField(inTiff, TIFFTAG_TILEWIDTH, &tileWidth) ||
24-
!TIFFGetField(inTiff, TIFFTAG_TILELENGTH, &tileLength)) {
25-
cerr << "Input TIFF is not tiled." << endl;
26-
TIFFClose(inTiff);
27-
return false;
28-
}
29-
3022
// Get image width, height, and other necessary tags
31-
TIFFGetField(inTiff, TIFFTAG_IMAGEWIDTH, &width);
32-
TIFFGetField(inTiff, TIFFTAG_IMAGELENGTH, &height);
23+
TIFFGetField(inTiff, TIFFTAG_IMAGEWIDTH, &w);
24+
TIFFGetField(inTiff, TIFFTAG_IMAGELENGTH, &h);
3325

3426
uint16_t samplesPerPixel = 1;
3527
TIFFGetField(inTiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel);
@@ -41,64 +33,190 @@ bool Depthmap::load(const char *tiff) {
4133

4234
uint16_t bitsPerSample = 32;
4335
TIFFGetField(inTiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
44-
if(bitsPerSample != 32) {
45-
cerr << "Samples should be a float 32 bit" << endl;
36+
if(bitsPerSample != 32 && bitsPerSample !=1) {
37+
cerr << "Samples should be a float 32 bit or 1 bit boolean" << endl;
4638
TIFFClose(inTiff);
4739
return false;
4840
}
4941

5042
uint16_t sampleFormat = SAMPLEFORMAT_IEEEFP; // Floating-point data
51-
TIFFGetField(inTiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
43+
//TIFFGetField(inTiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
44+
if (!TIFFGetField(inTiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat)) {
45+
cerr << "Failed to retrieve SAMPLEFORMAT tag." << endl;
46+
TIFFClose(inTiff);
47+
return false;
48+
}
5249

53-
//TODO: controllare che sia effettivamenet floating point 32 bit
50+
values.resize(w * h);
5451

55-
// Compute tile size and total number of tiles
52+
// Check if the TIFF is tiled
53+
uint32_t tileWidth, tileLength;
54+
if (!TIFFGetField(inTiff, TIFFTAG_TILEWIDTH, &tileWidth) ||
55+
!TIFFGetField(inTiff, TIFFTAG_TILELENGTH, &tileLength)) {
56+
return loadStripedTiff(inTiff, values, w, h, bitsPerSample);
57+
} else {
58+
return loadTiledTiff(inTiff, values, w, h, tileWidth, tileLength, bitsPerSample);
59+
}
5660
tsize_t tileSize = TIFFTileSize(inTiff);
5761
if (tileSize == 0) {
5862
cerr << "Error computing tile size." << endl;
5963
TIFFClose(inTiff);
6064
return 1;
6165
}
6266

63-
uint32_t numTilesX = (width + tileWidth - 1) / tileWidth;
64-
uint32_t numTilesY = (height + tileLength - 1) / tileLength;
67+
return true;
6568

66-
elevation.resize(width * height * samplesPerPixel);
67-
vector<float> tileData(tileSize / sizeof(float));
69+
}
70+
//TODO: controllare che sia effettivamenet floating point 32 bit
6871

69-
for (uint32_t y = 0; y < numTilesY; ++y) {
70-
for (uint32_t x = 0; x < numTilesX; ++x) {
71-
uint32_t tileIndex = TIFFComputeTile(inTiff, x * tileWidth, y * tileLength, 0, 0);
7272

73-
if (TIFFReadEncodedTile(inTiff, tileIndex, tileData.data(), tileSize) < 0) {
74-
cerr << "Error reading tile " << tileIndex << endl;
75-
TIFFClose(inTiff);
76-
return 1;
77-
}
73+
bool Depthmap::loadTiledTiff(TIFF* inTiff, vector<float> &values, uint32_t w, uint32_t h,
74+
uint32_t tileWidth, uint32_t tileLength, uint32_t bitsPerSample){
7875

79-
for (uint32_t tileY = 0; tileY < tileLength; ++tileY) {
80-
uint32_t dstY = y * tileLength + tileY;
81-
if(dstY >= height)
82-
break;
83-
for (uint32_t tileX = 0; tileX < tileWidth; ++tileX) {
84-
uint32_t srcIndex = tileY * tileWidth + tileX;
85-
uint32_t dstX = x * tileWidth + tileX;
76+
tsize_t tileSize = TIFFTileSize(inTiff);
77+
if (tileSize == 0) {
78+
cerr << "Error computing tile size." << endl;
79+
TIFFClose(inTiff);
80+
return false;
81+
}
82+
// Compute tile size and total number of tiles
83+
84+
uint32_t numTilesX = (w + tileWidth - 1) / tileWidth;
85+
uint32_t numTilesY = (h + tileLength - 1) / tileLength;
86+
87+
88+
if(bitsPerSample==32){
89+
vector<float> tileData(tileSize / sizeof(float));
90+
91+
for (uint32_t y = 0; y < numTilesY; ++y) {
92+
for (uint32_t x = 0; x < numTilesX; ++x) {
93+
uint32_t tileIndex = TIFFComputeTile(inTiff, x * tileWidth, y * tileLength, 0, 0);
94+
95+
if (TIFFReadEncodedTile(inTiff, tileIndex, tileData.data(), tileSize) < 0) {
96+
cerr << "Error reading tile " << tileIndex << endl;
97+
TIFFClose(inTiff);
98+
return 1;
99+
}
100+
101+
for (uint32_t tileY = 0; tileY < tileLength; ++tileY) {
102+
uint32_t dstY = y * tileLength + tileY;
103+
if(dstY >= height)
104+
break;
105+
for (uint32_t tileX = 0; tileX < tileWidth; ++tileX) {
106+
uint32_t srcIndex = tileY * tileWidth + tileX;
107+
uint32_t dstX = x * tileWidth + tileX;
108+
109+
if (dstX >= width) {
110+
continue;
111+
}
86112

87-
if (dstX >= width) {
88-
continue;
113+
uint32_t dstIndex = (dstY * w + dstX);
114+
values[dstIndex] = tileData[srcIndex];
89115
}
116+
}
117+
}
118+
}
119+
}
120+
if(bitsPerSample==1){
121+
unsigned char * tileData= new unsigned char [tileSize];
122+
123+
for (uint32_t y = 0; y < numTilesY; ++y) {
124+
for (uint32_t x = 0; x < numTilesX; ++x) {
125+
uint32_t tileIndex = TIFFComputeTile(inTiff, x * tileWidth, y * tileLength, 0, 0);
126+
127+
if (TIFFReadEncodedTile(inTiff, tileIndex, tileData, tileSize) < 0) {
128+
cerr << "Error reading tile " << tileIndex << endl;
129+
TIFFClose(inTiff);
130+
return 1;
131+
}
90132

91-
uint32_t dstIndex = (dstY * width + dstX) * samplesPerPixel;
92-
elevation[dstIndex] = tileData[srcIndex];
133+
for (uint32_t tileY = 0; tileY < tileLength; ++tileY) {
134+
uint32_t dstY = y * tileLength + tileY;
135+
if(dstY >= height)
136+
break;
137+
for (uint32_t tileX = 0; tileX < tileWidth; ++tileX) {
138+
uint32_t srcIndex = tileY * tileWidth + tileX;
139+
uint32_t dstX = x * tileWidth + tileX;
140+
141+
if (dstX >= width) {
142+
continue;
143+
}
144+
uint32_t bytePos = srcIndex >> 3;
145+
uint32_t bitPos = srcIndex & 7;
146+
uint32_t dstIndex = (dstY * w + dstX);
147+
148+
values[dstIndex] = (tileData[bytePos] & (1 << bitPos)) != 0;
149+
}
93150
}
94151
}
95152
}
153+
delete[] tileData;
96154
}
155+
return true;
156+
}
157+
158+
bool Depthmap::loadStripedTiff(TIFF* inTiff, std::vector<float> &values, uint32_t& w, uint32_t& h, uint32_t bitsPerSample){
159+
160+
tsize_t scanLineSize = TIFFScanlineSize(inTiff);
161+
if (scanLineSize == 0) {
162+
cerr << "Error computing strip size." << endl;
163+
TIFFClose(inTiff);
164+
return false;
165+
}
166+
167+
// Temporary buffer for reading one strip of data
168+
if(bitsPerSample==32) {
169+
vector<float> stripData(scanLineSize / sizeof(float));
170+
171+
for (uint32_t row = 0; row < h; ++row) {
172+
// Read the current strip
173+
if (TIFFReadScanline(inTiff, stripData.data(), row, 1) < 0) {
174+
cerr << "Error reading strip " << row << endl;
175+
TIFFClose(inTiff);
176+
return false;
177+
}
178+
179+
for (uint32_t col = 0; col < w; ++col) {
180+
uint32_t dstIndex = row * w + col;
181+
values[dstIndex] = stripData[col];
182+
}
183+
}
184+
}
185+
if(bitsPerSample==1) {
186+
unsigned char * stripData= new unsigned char [scanLineSize];
187+
188+
for (uint32_t row = 0; row < h; ++row) {
189+
// Read the current strip
190+
if (TIFFReadScanline(inTiff, stripData, row) < 0) {
191+
cerr << "Error reading strip " << row << endl;
192+
TIFFClose(inTiff);
193+
return false;
194+
}
195+
196+
for (uint32_t col = 0; col < w; ++col) {
197+
uint32_t bytePos = col >> 3;
198+
uint32_t bitPos = 7 - (col & 7);
199+
uint32_t dstIndex = row * w + col;
97200

98-
TIFFClose(inTiff);
99-
//togli estensione dal nome rimpiazza con xml e lo passi a loadXml
201+
202+
values[dstIndex] = (stripData[bytePos] & (1 << bitPos)) != 0;
203+
cout << values[dstIndex];
204+
}
205+
cout << endl;
206+
}
207+
delete[] stripData;
208+
}
209+
return true;
210+
}
211+
212+
bool Depthmap::load(const char *tiff) {
213+
if (!loadTiff(tiff, elevation, width, height)) {
214+
cerr << "Failed to load TIFF file: " << tiff << endl;
215+
return false;
216+
}
100217
QString tiffPath = QString(tiff);
101218
QString xmlPath = tiffPath.left(tiffPath.lastIndexOf('.')) + ".xml";
219+
102220
if (!loadXml(xmlPath)) {
103221
cerr << "Failed to load XML file: " << xmlPath.toStdString() << endl;
104222
return false;
@@ -155,12 +273,6 @@ bool Depthmap::loadXml(const QString &xmlPath){
155273
}
156274

157275
void Depthmap::computeNormals() {
158-
float min = 1e20f;
159-
float max = -1e20f;
160-
for(float h: elevation) {
161-
min = std::min(min, h);
162-
max = std::max(max, h);
163-
}
164276

165277
normals.resize(width*height);
166278

@@ -225,10 +337,9 @@ void Depthmap::projectToCameraDepthMap(const Camera& camera, const QString& outp
225337

226338
Eigen::Vector3f realCoordinates = pixelToRealCoordinates(x, y, pixelZ);
227339
Eigen::Vector3f imageCoords = camera.projectionToImage(realCoordinates);
228-
if(pixelZ > 0){
229-
minZ = std::min(minZ, pixelZ);
230-
maxZ = std::max(maxZ, pixelZ);
231-
}
340+
minZ = std::min(minZ, imageCoords[2]);
341+
maxZ = std::max(maxZ, imageCoords[2]);
342+
232343
}
233344
}
234345
if (minZ >= maxZ) {
@@ -237,27 +348,44 @@ void Depthmap::projectToCameraDepthMap(const Camera& camera, const QString& outp
237348
}
238349
for (int y = 0; y < height; y++) {
239350
for (int x = 0; x < width; x++) {
351+
if(mask[x+ y *width]==0.0f)
352+
continue;
240353
float pixelZ = elevation[x + y * width];
241354

242-
if (pixelZ <= 0) continue;
243-
int pixelValue = (int)round(((pixelZ - minZ) / (maxZ - minZ)) * 255);
244-
pixelValue = std::min(std::max(pixelValue, 0), 255);
245-
246355
Eigen::Vector3f realCoordinates = pixelToRealCoordinates(x, y, pixelZ);
247356
Eigen::Vector3f imageCoords = camera.projectionToImage(realCoordinates);
357+
int pixelValue = (int)round(((imageCoords[2] - minZ) / (maxZ - minZ)) * 255);
358+
pixelValue = std::min(std::max(pixelValue, 0), 255);
359+
360+
int imageX = (int)round(imageCoords[0]);
361+
int imageY = (int)round(imageCoords[1]);
248362

249-
int imageX = (int)round(imageCoords[0]);
250-
int imageY= (int)round(imageCoords[1]);
251363
if (imageX >= 0 && imageX < camera.width && imageY >= 0 && imageY < camera.height) {
252364
depthMapImage.setPixel(imageX, imageY, qRgb(pixelValue, pixelValue, pixelValue));
253365
//cout << "Pixel projected (" << x << ", " << y << ") -> (" << imageX << ", " << imageY << "), Z = "
254-
// << pixelZ << ", pixelValue = " << pixelValue << endl;
366+
// << pixelZ << ", pixelValue = " << pixelValue << endl;
255367
}
256368
}
257369
}
258370
depthMapImage.save(outputPath, "png");
259371
}
260372

373+
bool Depthmap::loadMask(const char *tifPath){
374+
//loaded masq orthoplane MicMac
375+
uint32_t w, h;
376+
if (!loadTiff(tifPath, mask, w, h)) {
377+
cerr << "Failed to load TIFF file: " << tifPath << endl;
378+
return false;
379+
}
380+
if(width != w || height != h){
381+
cerr << "Mask is not consistent with height or width" << endl;
382+
return false;
383+
}
384+
385+
return true;
386+
387+
}
388+
261389
void Depthmap::depthIntegrateNormals(){
262390
if (normals.empty()){
263391
cerr << "Error: no normals found" << endl;
@@ -300,7 +428,7 @@ void Depthmap::resizeNormals (int factorPowerOfTwo, int step = 1) {
300428

301429
if (srcX < width && srcY < height) {
302430

303-
// 1. produrre l'array dx e dy derivates resample derivates e poi le converto in normali
431+
// 1. create the array dx and dy, after convert to normals
304432
Eigen::Vector3f normal = normals[srcX + srcY * width];
305433
float dzdx = -normal.x() / normal.z();
306434
float dzdy = -normal.y() / normal.z();
@@ -320,7 +448,6 @@ void Depthmap::resizeNormals (int factorPowerOfTwo, int step = 1) {
320448
}
321449

322450
/*
323-
// prendi normali calcoli dx e dy e fai la media
324451
resizedNormals[y * targetWidth + x] = avgNormal / (factor * factor);
325452
}*/
326453

@@ -331,10 +458,7 @@ void Depthmap::resizeNormals (int factorPowerOfTwo, int step = 1) {
331458

332459
//QString filename = "/Users/erika/Desktop/testcenterRel_copia/photogrammetry/surface.jpg";
333460
//saveNormals(filename.toStdString().c_str());
334-
//chiama l'integrale integra le normali e salva il ply
335461
//depthIntegrateNormals();
336-
//QString plyFilename = "/Users/erika/Desktop/testcenterRel_copia/photogrammetry/resize_normals.obj";
337-
//saveObj(plyFilename.toStdString().c_str());
338462

339463
}
340464

@@ -362,7 +486,6 @@ void Depthmap::saveObj(const char *filename){
362486
}
363487
QTextStream out(&file);
364488

365-
//2. itera su i valori di vettori x e y prendi heights di x e y, converti x e y come pixeltoreal chiamala
366489
for (uint32_t y = 0; y < height; y++) {
367490
for (uint32_t x = 0; x < width; x++) {
368491
float z = elevation[x + y * width];
@@ -451,11 +574,6 @@ bool Camera::loadXml(const QString &pathXml){
451574
qDebug() << "Error to download the parameters to:" << fullInternePath;
452575
return false;
453576
}
454-
//fai Qdir trova la directory dove si trova xml con QFileinfo.path ti dice dove è la dir
455-
// cd .. per salire a photogrammetry
456-
//crea percorso con QDir FilePath
457-
// chiama loadInterne par e controlla return
458-
// assume that path is relative to the photogrammetry folder
459577

460578
return true;
461579
//autocal_foc.xml
@@ -482,9 +600,6 @@ bool Camera::loadInternParameters(const QString &internePath){
482600
return false;
483601
}
484602

485-
//pp r1 r2 ecc.
486-
//metti in 2 funzioni loadinternParameters
487-
488603
QDomElement sizeImg = calibNode.firstChildElement("SzIm");
489604
if (!sizeImg.isNull()) {
490605
QStringList dimensions = sizeImg.text().split(" ");
@@ -532,8 +647,7 @@ bool Camera::loadInternParameters(const QString &internePath){
532647
return true;
533648

534649
}
535-
// prendi vector3f che ritorna pixelreal ti ritorna una posizione 3d, applichi la trasformazione: proiezione usando la camera
536-
// ritorna pixel x e y img di l12 ori coord di pixel devono finire nell'ori-rel
650+
537651
// Pc = Rk(Pg − Ok)
538652
// Pg = Ground point Pc = point camera. x y z orientati come la camera, moltiplica la matrice. Poi fai la proiezione.
539653
Eigen::Vector3f Camera::projectionToImage(Eigen::Vector3f realPosition) const{

0 commit comments

Comments
 (0)