Reading *.mhd/*.raw format 3D images in ITK - c++

How to load and write .mhd/.raw format 3D images in ITK? I have tried to use the following code but it is not getting loaded as the dimension of the loaded image is displayed as 0,0,0.
Can someone please point out the mistake I am making?
typedef float InputPixelType;
const unsigned int DimensionOfRaw = 3;
typedef itk::Image< InputPixelType, DimensionOfRaw > InputImageType;
//typedef itk::RawImageIO<InputPixelType, DimensionOfRaw> ImageIOType;
typedef itk::ImageFileReader<InputImageType > ReaderType;
/*
* --------------------Loader and saver of Raws, as well the function that takes a resulting (from inference matrix/vector) and creates a Raw out of it.-----------------------
*/
InputImageType::Pointer loadRawImageItk( std::string RawFullFilepathname, ReaderType::Pointer & RawImageIO ) {
//http://www.itk.org/Doxygen/html/classitk_1_1Image.html
//http://www.itk.org/Doxygen/html/classitk_1_1ImageFileReader.html
typedef itk::ImageFileReader<InputImageType> ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(RawFullFilepathname);
//ImageIOType::Pointer RawImageIO = ImageIOType::New();
reader->SetImageIO( RawImageIO );
try {
reader->Update();
} catch (itk::ExceptionObject& e) {
std::cerr << e.GetDescription() << std::endl;
exit(1); // You can choose to do something else, of course.
}
//InputImageType::Pointer inputImage = reader->GetOutput();
InputImageType::Pointer inputImage = reader->GetOutput();
return inputImage;
}
int saveRawImageItk( std::string RawFullFilepathname, InputImageType::Pointer & outputImageItkType , ImageIOType::Pointer & RawImageIO) {
std::cout << "Saving image to: " << RawFullFilepathname << "\n";
typedef itk::ImageFileWriter< InputImageType > Writer1Type;
Writer1Type::Pointer writer1 = Writer1Type::New();
writer1->SetInput( outputImageItkType );
writer1->SetFileName( RawFullFilepathname );
writer1->SetImageIO( RawImageIO ); //seems like this is useless.
// Execution of the writer is triggered by invoking the \code{Update()} method.
try
{
writer1->Update();
}
catch (itk::ExceptionObject & e)
{
std::cerr << "exception in file writer " << std::endl;
std::cerr << e.GetDescription() << std::endl;
std::cerr << e.GetLocation() << std::endl;
return 1;
}
return 0;
}

I have just read the mhd and raw files in Python successfully using the following SimpleITK code:
import SimpleITK as sitk
import numpy as np
def load_itk_image(filename):
itkimage = sitk.ReadImage(filename)
numpyImage = sitk.GetArrayFromImage(itkimage)
return numpyImage
Maybe you can use it as a reference.
Whether you should use the ReadImage function instead of the ImageFileReader? You can have a try.

A few good examples of file reading depending on a known format are found here.
reader->SetImageIO( RawImageIO );
seems the incorrect thing to do here if you are loading both .mhd and .raw files as they are seperate formats, MetaImage vs Raw format where you do and don't know the image size, origin, spacing etc based on the absense or presense of a header.
How are you determining the size of the image and getting (0,0,0)? image->GetSize()?
Can you provide test data?
https://itk.org/Wiki/ITK/Examples/IO/ReadUnknownImageType
https://itk.org/ITKExamples/src/IO/ImageBase/RegisterIOFactories/Documentation.html

Related

Could not found the resource definition:BinOcaf.StoragePlugin?

I have the following code, and can be compiled, but when I run it, it fails with error of missing resource.
I have checked the cascade installer and everything is clicked and installed. How could I fix this?
#include <TDocStd_Application.hxx>
#include <TDataStd_Integer.hxx>
int main()
{
Handle(TDocStd_Application) app = new TDocStd_Application;
Handle(TDocStd_Document) doc;
app->NewDocument("BinOcaf", doc);
if (doc.IsNull())
{
std::cout << "Error: cannot create an OCAF document." << std::endl;
return 1;
}
// to access the main label, the transient data framework
TDF_Label mainLab = doc->Main();
// attach some integer value to this label
TDataStd_Integer::Set(mainLab, 1002);
// save document to file
PCDM_StoreStatus sstatus = app->SaveAs(doc, "C:/Users/Administrator/Desktop/test.cbf");
if (sstatus != PCDM_SS_OK)
{
app->Close(doc);
std::cout << "cannot write OCAF document." << std::endl;
return 1;
}
// release the data of doc
app->Close(doc);
return 0;
}
Ok, so after some head scratching I realized one thing. Forgot to define format.
just add the line of code to the main function would fix the problem.
BinDrivers::DefineFormate(app);

Handle PostgreSQL transaction errors in GDALVectorTranslate

In c++ I'm using the GDAL library for importing geo-spatial files into Postgres/PostGIS.
The GDAL library will create a table in the Postgres database and insert the data. But I can't figure out how to handle errors during the inserting of data.
I'm using GDALVectorTranslate https://gdal.org/api/gdal_utils.html#gdal__utils_8h_1aa176ae667bc857ab9c6016dbe62166eb
If an Postgres error occurs the error text will be outputted and the program continues to run. I would like to handle these Postgres errors.
An error could be:
ERROR 1: INSERT command for new feature failed.
ERROR: invalid byte sequence for encoding "UTF8": 0xe5 0x20 0x46
For now I let my program count the rows in the destination table and if zero then assume error. But that doesn't work if appending to an existing table.
auto *dst = (GDALDataset *) GDALVectorTranslate(nullptr, pgDs, 1, &sourceDs, opt, &bUsageError);
if (dst == nullptr) {
std::cout << "ERROR! Couldn't create table" << std::endl;
return FALSE;
} else {
OGRLayer *layer = dst->GetLayerByName(altName);
// Here the rows are counted
if (layer->GetFeatureCount() == 0) {
std::cout << "ERROR! Insert failed" << std::endl;
return FALSE;
}
std::cout << " Imported";
return TRUE;
}
You can register your own error handler to log and count the underlying errors:
struct {/*members for handling errors*/} ctx;
static void myErrorHandler(CPLErr e, CPLErrorNum n, const char* msg) {
ctx *myctx = (ctx*)CPLGetErrorHandlerUserData();
/* do something with ctx to log and increment error count */
}
int myTranslateFunc() {
ctx myctx; //+initialization
CPLPushErrorHandlerEx(&myErrorHandler,&myctx);
auto *dst = (GDALDataset *) GDALVectorTranslate(nullptr, pgDs, 1, &sourceDs, opt, &bUsageError);
CPLPopErrorHandler();
//inspect myctx for potential errors
}

CGAL How can I copy properties from Point_set to Surface mesh

First off, I'm aware of the CGAL GIS tutorial, but I just can't seem to copy properties from Point_set to surface mesh.
Any way, I'm loading the LIDAR point cloud to the point set as follows:
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point = Kernel::Point_3;
using Point_set = CGAL::Point_set_3<Point>;
std::ifstream ifile("input.ply", std::ios_base::binary);
ifile >> point_set;
std::cerr << point_set.size() << " point(s) read" << std::endl;
ifile.close();
I can get the properties via
auto props = point_set.properties();
for (const auto& item : props)
std::cerr << item << std::endl;
// I do know that there exist property "classification" that is of unsigned char type
Point_set::Property_map<unsigned char> original_class_map
= point_set.property_map<unsigned char>("classification").first;
Then, I had tried to set the mesh and had added vertex property, using the code from above mentioned CGAL tutorial. The code below set the point's z coordinate as a property.
auto idx_to_point_with_info
= [&](const Point_set::Index& idx) -> std::pair<Point, Point_set::Index> {
return std::make_pair(point_set.point(idx), idx);
};
using Vbi = CGAL::Triangulation_vertex_base_with_info_2<Point_set::Index, Projection_traits>;
using Fbi = CGAL::Triangulation_face_base_with_info_2<int, Projection_traits>;
using TDS = CGAL::Triangulation_data_structure_2<Vbi, Fbi>;
using TIN_with_info = CGAL::Delaunay_triangulation_2<Projection_traits, TDS>;
TIN_with_info tin_with_info(
boost::make_transform_iterator(point_set.begin(), idx_to_point_with_info),
boost::make_transform_iterator(point_set.end(), idx_to_point_with_info));
auto classification_value = [&](const TIN_with_info::Vertex_handle vh) -> double
{
return vh->point().z();
};
for (TIN_with_info::Vertex_handle vh : tin_with_info.all_vertex_handles())
{ // should work without classification_value, just plain vh->info() = vh->point().z();
vh->info() = classification_value(vh);
}
using Mesh = CGAL::Surface_mesh<Point>;
Mesh tin_class_mesh;
Mesh::Property_map<Mesh::Vertex_index, double> class_map
= tin_class_mesh.add_property_map<Mesh::Vertex_index, double>("v:class").first;
CGAL::copy_face_graph(tin_with_info, tin_class_mesh,
CGAL::parameters::vertex_to_vertex_output_iterator(
boost::make_function_output_iterator(class_lambda)));
std::cerr << tin_class_mesh.number_of_vertices() << " vs " << point_set.size() <<std::endl;
Now, this works just fine, I had successfully set the z coordinate as a property on a mesh.
But, I just can't figure out how can I copy the classification property from the point_set to the tin_class_mesh. I know that I'd need to change double to unsigned char in the code, but I don't know how to access the property from the point_set and assign it to the corresponding vertex in tin_class_mesh. What am I doing wrong?
As a side note, the interesting part here is that the number of tin_colored_mesh.number_of_vertices() differs slightly from the point_set.size(). Why is that?

FreeType2 FT_Outline_Decompose returns huge numbers

I am trying to read glyph outline for a character using FreeType lib.I load font from a standard .ttf file.Till now I was using outline tags to convert outline to path elements like segments and bezier curves.Then I found FT_Outline_Decompose which is a part of the lib.But when I am using it,the decomposed data values are huge.Every point on the path as a value of ~ 859722XXX .So even the down-scaling with factor of 64 as it's suggested by examples doesn't help to get pixel size values.
My code goes like this:
const char* fontFile ="fonts/Verdana.ttf";
std::string chars("Uta \n");
char charcode = chars[0];
FT_Library defLibHandle;
FT_Error err = FT_Init_FreeType(&defLibHandle);
if(err){
printf(ft_errors[err].err_msg);
throw;
}
FT_Face faceHandle;
err = FT_New_Face(defLibHandle,fontFile,0,&faceHandle);
if(err){
printf(ft_errors[err].err_msg);
throw;
}
FT_Glyph glyph;
// load glyph
err = FT_Load_Char(faceHandle,
charcode,
FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE);
if (err) {
std::cout << "FT_Load_Glyph: error\n";
}
//FT_Get_Glyph(faceHandle->glyph, &glyph);
FT_Outline outline = faceHandle->glyph->outline;
if (faceHandle->glyph->format != ft_glyph_format_outline) {
std::cout << "not an outline font\n";
}
FT_Outline_Funcs funcs;
funcs.move_to = (FT_Outline_MoveTo_Func)&moveTo;
funcs.line_to = (FT_Outline_LineTo_Func)&lineTo;
funcs.conic_to = (FT_Outline_ConicTo_Func)&conicTo;
funcs.cubic_to = (FT_Outline_CubicTo_Func)&cubicTo;
// trace outline of the glyph
err = FT_Outline_Decompose(&outline,
&funcs, nullptr);
if (err) {
std::cout <<ft_errors[err].err_msg ;
}
Now, in the callbacks like moveTo() I attempt to resize:
int moveTo(FT_Vector* to, void* fp) {
pathRef->moveTo(ftVecToFloat(to)); ///
// ftVecToFloat is "float(f) / 64.0f" ///
return 0;
}
But the initial FT_Vector value is so huge that the division by 64.0 still doesn't matters.
set
funcs.shift = 0;
funcs.delta = 0;
will work

how can i get file dropped to which gtkmm image widget

....
std::vector<Gtk::TargetEntry> listTargets;
listTargets.push_back( Gtk::TargetEntry("STRING") );
listTargets.push_back( Gtk::TargetEntry("text/plain") );
image1->drag_dest_set(listTargets);
image1->signal_drag_data_received().connect(sigc::mem_fun(*this,
&mainWindow::drop_event) );
image2->drag_dest_set(listTargets);
image2->signal_drag_data_received().connect(sigc::mem_fun(*this,
&mainWindow::drop_event) );
....
and my drop&drop event handler function :
void mainWindow::drop_event(
const Glib::RefPtr<Gdk::DragContext>& context, int, int,
const Gtk::SelectionData& selection_data, guint, guint time)
{
std::cout << selection_data.get_data_as_string() << std::endl;
}
I can get file locations that "dragged to image widgets" with this code. output is like this:
file:////opt/google/chrome/google-chrome.desktop
file:////var/www/index.html
file:///opt/libreoffice4.1/LICENSE.html
it's ok, i can. But, how can i get: file dropped to which image (image1 or image2 widgets) like this:
dropped to **image1** : file:////opt/google/chrome/google-chrome.desktop
dropped to **image2** : file:////var/www/index.html
dropped to **image1** : file:///opt/libreoffice4.1/LICENSE.html
thanks...
sigc allows you to bind extra arguments to your handlers.
Hander becomes:
void mainWindow::drop_event(
const Glib::RefPtr<Gdk::DragContext>& context, int, int,
const Gtk::SelectionData& selection_data, guint, guint time,
Glib::ustring whichImage)
{
std::cout << "dropped to" << whichImage << ":" << selection_data.get_data_as_string() << std::endl;
}
And the connect then is:
image1->signal_drag_data_received().connect(sigc::bind<Glib::ustring>(sigc::mem_fun(*this,
&mainWindow::drop_event), "image1" ));
image2->signal_drag_data_received().connect( sigc::bind<Glib::ustring>(sigc::mem_fun(*this,
&mainWindow::drop_event), "image2"));