I have a complex array created and stored in hdf5 format as follows:
import numpy as np
import h5py
a = np.random.random((50,50))
b = np.random.random((50,50))
a = a+1j*b
with h5py.File('random.hdf5','w') as f:
dset = f.create_dataset('vec',data=a,dtype='c16',compression="gzip",compression_opts=4)
f.close()
Now I am trying to read this file random.hdf5 via a Fortran routine.
Fortran has no native complex data types for hdf5. How do I go about reading this file?
(Also if it helps, I am using Intel fortran compiler)
Related
I'm trying to implement and run OpenCV sample code Reading Geospatial Raster files with GDAL
For DEM model, i download N37W123.hgt.zip from the SRTM file located at the USGS , (that is in the Results section of that page).
but, DEM model not loaded to cv::Mat dem by cv::Mat dem = cv::imread(argv[2], cv::IMREAD_LOAD_GDAL | cv::IMREAD_ANYDEPTH ); and i get run time error throw std::runtime_error("DEM image type must be CV_16SC1");
1) Why is this happening?
2) All DEM data type are 16 signed integer. is it ok?
3) How can read DEM model block with GDALDataset::RasterIO or GDALRasterBand::ReadBlock directly?
Most Likely you have to enable/set WITH_GDAL flag to true in CMake while building opencv.
for reference:
https://docs.opencv.org/4.4.0/d4/da8/group__imgcodecs.html#imread
gdal is most likely expecting an HGT file, not a ZIP file: Link.
In Python you would extract the archive first using the zipfile module, then you can access the file directly into a numpy array:
from osgeo import gdal
ds = gdal.Open(filename)
data = ds.ReadAsArray()
EDIT: You've pointed out in a comment that you are using C++, so see the tutorial for reading the image directly: Link
I'm trying to read in a .mat file from Matlab using matio and the variable comes in with the the correct rank and dims, but the data is null:
mat_t *matfp;
matvar_t *matvar;
matfp = Mat_Open("the_file.mat",MAT_ACC_RDONLY);
matvar = Mat_VarReadInfo(matfp,"my_var");
assert(matvar->rank==2);
assert(nrows==matvar->dims[0] && ncols==matvar->dims[1]);
but
matvar->data==NULL
I'm assuming something is going wrong reading in the .mat file, but I'm not sure how to diagnose it.
You should check the MATLAB file version.
Maybe the file is written in MATLAB version 7.3 or with compression.
If you build your lib (matio) without zlib you can not read compressed data.
If you build without zlib and HDF5 you can not read file version 7.3 files.
To access the data of a variable you have to use Mat_VarRead() instead of Mat_VarReadInfo(). Otherwise matvar->data is NULL.
Based on the example given here, I have a file image loaded into memory as a string with a valid handler. This was done using H5LTopen_file_image().
How can I check that a file is a valid HDF5 file?
I found only a program called H5check, which has a complicated source code. So, I'm wondering, is there a simple function with a simple return value to verify that whatever in the hid_t handler is a valid HDF5 file?
In C++:
std::string filename = "foo.h5";
if(!H5::H5File::isHdf5(filename.c_str()))
{
std::string err_msg = filename + " is not an HDF5 file.\n";
throw std::logic_error(err_msg);
}
In Python, use
import h5py
if not h5py.is_hdf5('foo.h5'):
raise ValueError('Not an hdf5 file')
I am trying to convert a iamge loaded using PIL to a Cimg image object. I understand that Cimg is a c++ library and PIL is a python imaging library. Given an image url, my aim is to calculate the pHash of an image without writing it onto a disk. pHash module works with a Cimg image object and it has been implemented in C++. So I am planning to send the required image data from my python program to the c++ program using python extension binding. In the following code sniplet, I am loading the image from the given url:
//python code sniplet
import PIL.Image as pil
file = StringIO(urlopen(url).read())
img = pil.open(file).convert("RGB")
The Cimg image object that I need to construct looks as follows:
CImg ( const t *const values,
const unsigned int size_x,
const unsigned int size_y = 1,
const unsigned int size_z = 1,
const unsigned int size_c = 1,
const bool is_shared = false
)
I can get the width(size_x) and height(size_y) using img.size and can pass it to c++. I am unsure of how to fill 'values' field of the Cimg object? What kind of data structure to use to pass the image data from the python to c++ code?
Also, is there any other way to convert a PIL image to Cimg?
I assume that your main application is written in Python and you want to call C++ code from Python. You can achieve that by creating a "Python module" that will expose all native C/C++ functionality to Python. You can use a tool like SWIG to make your work easier.
That's the best solution of your problem that came to my mind.
The simplest way to pass an image from Python to a C++ CImg-based program is via a pipe.
So this a C++ CImg-based program that reads an image from stdin and returns a dummy pHash to the Python caller - just so you can see how it works:
#include "CImg.h"
#include <iostream>
using namespace cimg_library;
using namespace std;
int main()
{
// Load image from stdin in PNM (a.k.a. PPM Portable PixMap) format
cimg_library::CImg<unsigned char> image;
image.load_pnm("-");
// Save as PNG (just for debug) rather than generate pHash
image.save_png("result.png");
// Send dummy result back to Python caller
std::cout << "pHash = 42" << std::endl;
}
And here is a Python program that downloads an image from a URL, converts it into a PNM/PPM ("Portable PixMap") and sends it to the C++ program so it can generate and return a pHash:
#!/usr/bin/env python3
import requests
import subprocess
from PIL import Image
from io import BytesIO
# Grab image and open as PIL Image
url = 'https://i.stack.imgur.com/DRQbq.png'
response = requests.get(url)
img = Image.open(BytesIO(response.content)).convert('RGB')
# Generate in-memory PPM image which CImg can read without any libraries
with BytesIO() as buffer:
img.save(buffer,format="PPM")
data = buffer.getvalue()
# Start CImg passing our PPM image via pipe (not disk)
with subprocess.Popen(["./main"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc:
(stdout, stderr) = proc.communicate(input=data)
print(f"Returned: {stdout}")
If you run the Python program, you get:
Returned: b'pHash = 42\n'
I was assuming that sys.stdout would be referencing the same physical stream as iostreams::cout running in the same process, but this doesn't seem to be the case.
The following code, which makes a call to a C++ function with a python wrapper called "write", that writes to cout:
from cStringIO import StringIO
import sys
orig_stdout = sys.stdout
sys.stdout = stringout = StringIO()
write("cout") # wrapped C++ function that writes to cout
print "-" * 40
print "stdout"
sys.stdout = orig_stdout
print stringout.getvalue()
immediately writes "cout" to the console, then the separator "---...", and finally, as the return value of stringout.getvalue(), the string "stdout".
My intention was to capture in stringout also the string written to cout from C++.
Does anyone know what is going on, and if so, how I can capture what is written to cout in a python string?
Thanks in advance.
sys.stdout is a Python object that writes to standard output. It is not actually the standard output file handle; it wraps that file handle. Altering the object that sys.stdout points to in Python-land does not in any way affect the stdout handle or the std::cout stream object in C++.
With help from comp.lang.python and after some searching on this site:
As cdhowie pointed out, the standard output file handle has to be accessed at a lower level. In fact, its file descriptor can be obtained as sys.stdout.fileno() (which should be 1), and then os.dup and os.dup2 can be used.
I found this answer to a similar question very helpful.
What I really wanted was to capture the output in a string, not a file. The python StringIO class however doesn't have a file descriptor and cannot be used in place of an actual file, so I came up with the not fully satisfactory workaround in which a temporary file is written and subsequently read.
It cannot possibly be the same stream, as Python is written in
C, and not C++, and has no access to std::cout. Whether it
uses stdout or implements its own stream based on fd 1,
I don't know, but in any case, you'd be advised to flush between
writes using the two objects (Python and C++).