TIFF files garbled by ArrayFire (C++) - c++

I notice that this simple ArrayFire program is causing loaded TIFF images to be heavily distorted:
#include <iostream>
#include <arrayfire.h>
int main( int argc, char** argv ) {
af::array img = af::loadImage( argv[1] );
double mn, mx;
unsigned idxn, idxx;
af::min( &mn, &idxn, img );
af::max( &mx, &idxx, img );
std::cout << "Image size = " << img.dims()[0] << ", " << img.dims()[1] << '\n';
std::cout << "Data type = " << img.type() << '\n';
std::cout << "Min = " << mn << " (at " << idxn << ")\n";
std::cout << "Max = " << mx << " (at " << idxx << ")\n";
af::saveImage( argv[2], img );
return 0;
}
I then compile and run on a simple (monochrome) image:
./a.out orig.tif out.tif
with the following output:
Image size = 256, 256
Data type = 0
Min = 0 (at 65535)
Max = 81.5025 (at 31356)
When I visualize these images I get the following result:
which of course is not what ArrayFire is expected to do; I would expect it to dump the exact same image out since I didn't make any changes to it. Unfortunately I don't know enough about the TIFF image format or the graphics backend of ArrayFire to understand what is going on. Am I doing something wrong while loading the image? (I followed the ArrayFire documentation for loadImage and saveImage).
I also tried using loadImageNative and saveImageNative alternatively, but the latter returns a 4-layer TIFF image while the original image is only a 1-layer TIFF.
Any help at all from ArrayFire experts would be great.
Thanks!

Related

how to read and write an image using C++ in visual studio with ITK configured

I am a beginner to ITK and c++. I have the following code where I can get the height and width of an image. Instead of giving the input image in the console, I want to do it in the code itself. How do I directly give the input image to this code?
#include "itkImage.h"
#include "itkImageFileReader.h"
int main()
{
mat m("filename");
imshow("windowname", m);
}
// verify command line arguments
if( argc < 2 )
{
std::cout << "usage: " << std::endl;
std::cerr << argv[0] << " inputimagefile" << std::endl;
return exit_failure;
}
typedef itk::image<float, 2> imagetype;
typedef itk::imagefilereader<imagetype> readertype;
readertype::pointer reader = readertype::new();
reader->setfilename( argv[1] );
reader->update();
std::cout << reader->getoutput()->getlargestpossibleregion().getsize()[0] << " "
<< reader->getoutput()->getlargestpossibleregion().getsize()[1] << std::endl;
// an example image had w = 200 and h = 100 (it is wider than it is tall). the above output
// 200 100
// so w = getsize()[0]
// and h = getsize()[1]
// a pixel inside the region
itk::index<2> indexinside;
indexinside[0] = 150;
indexinside[1] = 50;
std::cout << reader->getoutput()-
>getlargestpossibleregion().isinside(indexinside) << std::endl;
// a pixel outside the region
itk::index<2> indexoutside;
indexoutside[0] = 50;
indexoutside[1] = 150;
std::cout << reader->getoutput()- >getlargestpossibleregion().isinside(indexoutside) << std::endl;
// this means that the [0] component of the index is referencing the left to right (column) index
// and the [1] component of index is referencing the top to bottom (row) index
return exit_success;
}
Change the line reader->setfilename( argv[1] ); by reader->setfilename( "C:/path/to/file.png" );
I assume that
mat m("filename");
imshow("windowname", m);
sneaked in from some unrelated code? Otherwise the example would not compile.

Reading out Pixel Values, png++, C++

I am trying to load the pixel rgb/ga information of a png image into a matrix, using the library png++, to do some computations with them.
My Code (which does not work at the moment):
#include <iostream>
#include <png++/image.hpp>
#include <png++/rgb_pixel.hpp>
int main(int argc, const char * argv[]) {
const std::string path="img_03.png";
png::image< png::basic_rgb_pixel <unsigned char> > pic(path);
pixel=pic.get_pixel(0, 0);
pixelp = &pixel;
std::cout << "value=" << pic[10][10].red << std::endl; //output: '?'
std::cout << "value=" << pixel.red << std::endl; //nothing
std::cout << "pointer=" << pixelp << std::endl; //delivers adress
pic.read(path);
std::cout << "value=" << pic[10][10].red << std::endl; //nothing
pic.write("picOutput.png"); //same picture
return 0;
}
However, none of those methods work to get the rgb values of each pixel.
If there is another way to get rgb/ga information of each pixel, please mention it.
The line pic.write("picOutput.png"); delivers the same png i loaded in the line pic.read(path). This is a personal exercise for me to get more used to C++, criticise my code as much as you can.
Thanks!
Here comes the solution:
change line:
std::cout << "value=" << pic[10][10].red << std::endl; //nothing
with:
std::cout << "value=" << (int) pic[10][10].red << std::endl; //nothing
because std::cout can't output types of unsigned char.
Thanks to Alex!
For in-depth explanation, look here:
cout not printing unsigned char

Magick++ get pixel color. pixelpacket doesnt seem to exist anymore

I'm trying to get the color of a pixel in a jpg image and all the tutorials I can find online say to use pixelpacket which doesnt exist anymore. searching and searching through google i've found that getvirtualpixels might be the new way but that doesnt seem to exist in the newest version either. so how do I get the color of pixels from an image with an image cache? I do not need to set any pixels btw.
Using windows10 and visual studio 2015
PixelPacket structures have been replaced with a pointer to Quantum data type. From Porting to ImageMagick Version 7, the key thing to understand is that a pixel can now have dynamic parts (or "traits" previously called as "channels").
ImageMagick version 7 supports any number of channels from 1 to 32 (and beyond) and simplifies access with a single method that returns an array of pixel channels of type Quantum.
You are now responsible for authoring code that handles deterministic (is that the right term?) pixel channels. For example...
Magick::Image rose("rose:");
const Magick::Quantum * q = rose.getConstPixels(5, 5, 1, 1);
size_t channel_length = rose.channels();
for (size_t k = 0; k < channel_length; k++ ) {
std::cout << "Channel " << k << " = ";
std::cout << q[k] << " of " << QuantumRange << std::endl;
}
/** Outputs
-------
Channel 0 = 13107 of 65535
Channel 1 = 12079 of 65535
Channel 2 = 11308 of 65535
*/
Without seeing your code, or understanding what your finial goal would be, I would guess that you really just want RGB info. If that's the case, the Magick::Image.getColor will work,
Magick::Image rose("rose:");
Magick::Color pixelColor = rose.pixelColor(5, 5);
std::cout << "Channel 0 = ";
std::cout << pixelColor.quantumRed() << " of " << QuantumRange << std::endl;
std::cout << "Channel 1 = ";
std::cout << pixelColor.quantumGreen() << " of " << QuantumRange << std::endl;
std::cout << "Channel 2 = ";
std::cout << pixelColor.quantumBlue() << " of " << QuantumRange << std::endl;
/** Outputs
-------
Channel 0 = 13107 of 65535
Channel 1 = 12079 of 65535
Channel 2 = 11308 of 65535
*/
But! Sometimes it's just easier to export the image data into a format you're already working with. For example, I might only need Green values as single-point float list.
Magick::Image rose("rose:");
Magick::PixelData pixelBlob(rose, "G", Magick::FloatPixel);
float * buffer = (float *)pixelBlob.data();
// ...

I'm trying to convert pixel data to an OpenCV Mat object

I have raw pixel data that I want to output via the opencv cvShowImage() function.
I have the following code:
#include <opencv2/highgui/highgui.hpp>
// pdata is the raw pixel data as 3 uchars per pixel
static char bitmap[640*480*3];
memcpy(bitmap,pdata,640*480*3);
cv::Mat mat(480,640,CV_8UC3,bitmap);
std::cout << mat.flags << ", "
<< mat.dims << ", "
<< mat.rows << ", "
<< mat.cols << std::endl;
cvShowImage("result",&mat);
Which outputs:
1124024336, 2, 480, 640
to the console, but fails to output the image with cvShowImage(). Instead throwing an exception with the message:
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat
I suspect the problem is in the way I create the mat object, but I am having a very hard time finding any more specific information on how I am supposed to do that.
I don't think CV_8UC3 is enough of a description for it to render the array of data. Doesn't it have to know whether the data is RGB or YUY2, etc.? How do I set that?
Try cv::imshow("result", mat) instead of mixing the old C and new C++ APIs. I expect casting a Mat to a CvArr* is the source of the problem.
So, something like this:
#include <opencv2/highgui/highgui.hpp>
// pdata is the raw pixel data as 3 uchars per pixel
static char bitmap[640*480*3];
memcpy(bitmap,pdata,640*480*3);
cv::Mat mat(480,640,CV_8UC3,bitmap);
std::cout << mat.flags << ", "
<< mat.dims << ", "
<< mat.rows << ", "
<< mat.cols << std::endl;
cv::imshow("result", mat);

QImage read pixel data with precision

Sorry for the basic question, I am just starting to use QImage for reading pixel data from an image file.
To understand the member functions, I tried to load an image file and tried to output the functions return values:
QString fileName = "pic1.bmp";
QImage myImage;
myImage.load( fileName );
std::cout << "width = " << myImage.width() << std::endl;
std::cout << "height = " << myImage.height() << std::endl;
std::cout << "dotspermeterX = " << myImage.dotsPerMeterX() << std::endl;
std::cout << "dotspermeterY = " << myImage.dotsPerMeterY() << std::endl;
QRectF myRect = myImage.rect();
std::cout << "rect = " << myRect.bottomLeft().x() << "," << myRect.bottomLeft().y()
<< " " << myRect.topRight().x() << "," << myRect.topRight().y() << std::endl;
The output I got was:
width = 858
height = 608
dotspermeterX = 4724
dotspermeterY = 4724
rect = 0,608 858,0
My questions are:
1. What is the difference between dots and pixels?
2. Does QImage work only with int pixels? Can't I read sub-pixel data for better precision?
To clarify my question, Following is a zoomed bitmap image of a diagonal line and I want to read all the small pixels/dots in this line. Is this possible?
As for the "dots per meter", you probably heard of "dots per inch" (or DPI). It's the same. If, for example, you have a 20 inch monitor with the horizontal resolution of X pixels, you will have Y "dots per inch" (or pixels per inch). If you then switch to a 40 inch monitor but with the same horizontal resolution X, then you have half the number of DPI, as the screen is now double as wide. So DPI (or PPI) can be seens as a measurement of the size of the pixels.
And no, I seriously doubt that QImage have any support for sub-pixel data.