Last active
October 17, 2024 23:09
-
-
Save discorev/bb64ead69c2a66c6fc57 to your computer and use it in GitHub Desktop.
C++ to use libtif to read a multi-page tiff and convert it to an opencv matrix for manipulation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <opencv2/core/core.hpp> | |
#include <opencv2/imgcodecs.hpp> | |
#include <opencv2/highgui/highgui.hpp> | |
#include <opencv2/imgproc/imgproc.hpp> | |
#include <iostream> | |
#include <string> | |
#include <tiffio.h> | |
using namespace cv; | |
using namespace std; | |
int main(int argc, char** argv) | |
{ | |
string imageName("file.tif"); // start with a default | |
// If there is an argument, read it in as the name of the image | |
if (argc > 1) | |
{ | |
imageName = argv[1]; | |
} | |
// Open the TIFF file using libtiff | |
TIFF* tif = TIFFOpen(imageName.c_str(), "r"); | |
// Create a matrix to hold the tif image in | |
Mat image; | |
// check the tif is open | |
if (tif) { | |
do { | |
unsigned int width, height; | |
uint32* raster; | |
// get the size of the tiff | |
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); | |
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); | |
uint npixels = width*height; // get the total number of pixels | |
raster = (uint32*)_TIFFmalloc(npixels * sizeof(uint32)); // allocate temp memory (must use the tiff library malloc) | |
if (raster == NULL) // check the raster's memory was allocaed | |
{ | |
TIFFClose(tif); | |
cerr << "Could not allocate memory for raster of TIFF image" << endl; | |
return -1; | |
} | |
// Check the tif read to the raster correctly | |
if (!TIFFReadRGBAImage(tif, width, height, raster, 0)) | |
{ | |
TIFFClose(tif); | |
cerr << "Could not read raster of TIFF image" << endl; | |
return -1; | |
} | |
image = Mat(width, height, CV_8UC4); // create a new matrix of w x h with 8 bits per channel and 4 channels (RGBA) | |
// itterate through all the pixels of the tif | |
for (uint x = 0; x < width; x++) | |
for (uint y = 0; y < height; y++) | |
{ | |
uint32& TiffPixel = raster[y*width+x]; // read the current pixel of the TIF | |
Vec4b& pixel = image.at<Vec4b>(Point(y, x)); // read the current pixel of the matrix | |
pixel[0] = TIFFGetB(TiffPixel); // Set the pixel values as BGRA | |
pixel[1] = TIFFGetG(TiffPixel); | |
pixel[2] = TIFFGetR(TiffPixel); | |
pixel[3] = TIFFGetA(TiffPixel); | |
} | |
_TIFFfree(raster); // release temp memory | |
// Rotate the image 90 degrees couter clockwise | |
image = image.t(); | |
flip(image, imae, 0); | |
imshow("TIF Image", image); // show the image | |
waitKey(0); // wait for anykey before displaying next | |
} while (TIFFReadDirectory(tif)); // get the next tif | |
TIFFClose(tif); // close the tif file | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment