How to create a mesh object in ITK using Python bindings? - python

I am trying to create a Mesh object in Python. I am using the python bindings which are being installed from the following web page. As far as the c++ code is concerned we can do it as follows
MeshType::Pointer mesh = MeshType::New();
I am very new to use even ITK. Have no idea how to create it. In the constructor of Mesh in the c++ documentation, it says one necessary argument which is the TPixelType. Unable to locate that as well.
Could anybody help me please with this.
Thanks

If I were you I would take a look at the Python bindings that come with ITK 4.0. You can get access to them by turning on the option WRAP_ITK_PYTHON in cmake.
Once, you compile ITK with the python bindings turned on you can create 2 mesh types out of the box:
import itk
meshType2D = itk.Mesh.D2Q.New()
meshType3D = itk.Mesh.D3Q.New()
alternatively you can explicitly instantiate your classes as follows:
import itk
meshType2D = itk.Mesh[itk.D, 2, itk.QuadEdgeMeshTraits.D2BBFF]
meshType3D = itk.Mesh[itk.D, 3, itk.QuadEdgeMeshTraits.D3BBFF]
This will give you 2 and 3 dimensional meshes of double type pixel values with default mesh traits. As far as pixel types in ITK go, these amount to the basic C++ variables types: double, float, unsigned int, etc. These basic types are wrapped in python and can be found in the ITK namespace: itk.D, itk.F, itk.UI, etc.

Related

Loading a Mesh in OpenCV Python with viz module

I am creating an AR-app, where you can virtually try on shoes. For now I have the location of the foot calculated using SolvePnp. Now I want to render the 3D object (.obj) file on top of the image, using the OpenCv Viz module. (Manually compiling worked)
I want to load the object as an cv::viz::Mesh object using the cv::viz::Mesh::load function, but I don't find the corresponding Python function call.
I tried
mesh = cv2.viz_Mesh()
mesh.load('shoe.obj', cv2.viz_Mesh_LOAD_OBJ)
and also
mesh = cv2.viz_Mesh_load('shoe.obj', cv2.viz_Mesh_LOAD_OBJ)
I always get the error:
AttributeError: 'cv2.viz_Mesh' object has no attribute 'load'
Using the dir() function from python I found all other methods except the load method, which is a static method (that's probably why it isn't here).
>>> dir(cv2) #contains the Viz Classes
['', ... , 'viz',... ,'viz_Mesh]
>>> dir(cv2.viz) #Stuff like Enums , Colors etc
['',...'Color_amethyst', ..., 'MOUSE_EVENT_MOUSE_DBL_CLICK'...]
>>> dir(cv2.viz_Mesh) #pyhton functions and other non static methods
['__class__', ... , 'colors','polygons']
Does someone know what the correct python call is?
Appendix: the cv2.viz_Mesh_LOAD_OBJ and cv2.viz_MESH_LOAD_OBJ represent only integers 2 ( = enums), thus
>>>print(cv2.viz_MESH_LOAD_OBJ)
>>>print(cv2.viz_Mesh_LOAD_OBJ)
2
2
I found the solution. I overlooked some methods in the dir(cv2.viz).
The correct python call would be
mesh = cv2.viz.readMesh('./shoe.ply')
It only accepts the path to .ply file, but not to .obj files (Version 4.5.5). Maybe other formats will be added in newer versions

how to write pybind11_module when used point cloud library

I am writing a python project, and I need a module of point cloud reconstruction to polygon mesh and other operations. So I write these modules in C++ by calling Point Cloud Library(PCL), Eigen and Pybind11. Except Eigen::Matrix, pcl::PointCloud, pcl::PolygonMesh, I still define some new classes. But in the interface function "PreProcess"(python call this function) I only use Eigen::Matrix and std::vector, which are all support by pybind11, PCL classes and my self-defined classes are only used in some middle sub functions.
I have tried some easy toy codes(only use Eigen and Pybind11), use the bellow "PYBIND11_MODULE" can be compiled successfully, Pybind can support Eigen::Matrix and C++ std::vector.
Now in my c++ project, when I using the same "PYBIND11_MODULE" with the essy toy code, it can not pass compiling, with error:
/home/helanyi/Documents/pgnn/utils/surface_reconstruct/src/test.cpp:931:16: error: expected constructor, destructor, or type conversion before ‘(’ token
PYBIND11_MODULE(process, m) {
So I want to ask that how do I write the "PYBIND11_MODULE"? Need I define the pcl classes and my self-defined classes in the "PYBIND11_MODULE"? Thank you so much!
PYBIND11_MODULE(process, m) {
m.doc() = "pybind11 example plugin";
m.def("PreProcess", &PreProcess);
}

Accessing webcam via DirectShow using COM with Python

I want to get low level access to webcam properties using DirectShow's IAMVideoProcAmp.
There are several Python modules )pywin32, pywintypes, comtypes, win32com, pythoncom) that are used in this context and they seem to be related somehow. But I have no clue where to start.
I found some examples (here, here, here) but I could not figure out how to get a IID / CLSID to use like
import win32com.client
clsid='{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'
ShellWindows=win32com.client.Dispatch(clsid)
or with a clear name like
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
or
from comtypes import client, GUID
graph = client.CreateObject(some_CLSID)
graph.QueryInterface(...)
Can someone help me with this?
I found another example (dshow.py), but it has some dependencies that I could not find (interfaces, uuids).
This page from Microsoft lists the procedures as
Call QueryInterface on the capture filter for the IAMVideoProcAmp interface.
or
Query the capture filter for the IAMCameraControl.
and states some C++ code for this:
// Query the capture filter for the IAMVideoProcAmp interface.
IAMVideoProcAmp *pProcAmp = 0;
hr = pCap->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
hr = m_pProcAmp->GetRange(VideoProcAmp_Brightness, &Min, &Max, &Step,
&Default, &Flags);
Edit:
I finally found some code that looks good so far:
jaraco
It seem to do exactly what I am trying to write and uses some elements from
DirectShow (see here):
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video claims to be "a port of the VideoCapture module in pure Python using ctypes and comtypes."
It is using a DirectShow.tlb file (whatever that is) to get the definitions
into comtypes
A type library (.tlb) is a binary file that stores information about a
COM or DCOM object's properties and methods in a form that is
accessible to other applications at runtime.
Identifying required values to replicate the code
At a second glance at the code excerpt at the end of your post, I realize that you only need the IID and not the CLSID for IAMVideoProcAmp in order to acquire an instance of it.
Looking at line 8733 of this source of strmif.h, noted as the required header for the interface, I found that IID_IAMVideoProcAmp is C6E13360-30AC-11d0-A18C-00A0C9118956.
Above this section of strmif.h, you can identify what integers correspond to which properties in the tagVideoProcAmpProperty enum, such as 0 for VideoProcAmp_Brightness. Below this section of strmif.h, you can identify what integers correspond to which functions in the IAMVideoProcAmpVtbl VTable, such as 3 for GetRange. I am unfamiliar with how to interact with COM objects in Python, but in Java you would need to determine these property and function indices in order to replicate the C++ code excerpts that demonstrate how to acquire an instance of IAmVideoProcAmp.
Acquiring an instance of IAMVideoProcAmp
As you may have noticed, the C++ code excerpt invokes QueryInterface on something called pCap and notes that you need to "Query the capture filter for the IAMVideoProcAmp interface." This sibling of the article you linked explains how to do this:
To create a DirectShow capture filter for the device, call the IMoniker::BindToObject method to get an IBaseFilter pointer. Then call IFilterGraph::AddFilter to add the filter to the filter graph:
IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
if (SUCCEEDED(hr))
{
hr = m_pGraph->AddFilter(pCap, L"Capture Filter");
}
Now that you know how to acquire pCap, you notice you need something called pMoniker, which is defined earlier in the same article. The code is fairly long so I omit it here.
Doing all of this in Python
As I noted earlier, I have never used any Python COM library, so I cannot easily whip up an example, but your goal should be to replicate in Python the function invocations made in the C++ examples to acquire an instance of IAMVideoProcAmp and modifying them to suit your needs.
I finally found some example library that is working:
jaraco
It does exactly what I am trying to achive and uses some elements from
DirectShow (see here):
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video claims to be "a port of the VideoCapture module in pure Python using ctypes and comtypes."
It is using a DirectShow.tlb file (whatever that is) to get the definitions
into comtypes
A type library (.tlb) is a binary file that stores information about a
COM or DCOM object's properties and methods in a form that is
accessible to other applications at runtime.
The imports are auto-generated in __init__.py and can be used easily:
from api.objects import ..., IMediaControl, IAMVideoProcAmp, IAMCameraControl, ...
and can be used
def _get_camera_control(self):
return self._get_graph_builder_interface(IAMCameraControl)
def get_camera_control_property(self, i):
video_properties = self._get_camera_control()
return video_properties.Get(i)
Then you can use the functions in combination with the enum stated in the docs, e.g.
# CameraControl_Exposure = 4
print(d.get_camera_control_property(4))

Virtual table in llvm (llvm-py)

I'm using llvm-py to create a DIY compiler for some artificial and need to have a virtual method table in the globe scope. My concept is to have several arrays of function pointers (one for each class). Unfortunately there's no LLVM IR Builder for a global scope and I cannot use ptrtoint in order to have uniform type of all array elements (otherwise I would store function addresses as 64-bit ints and cast them to appropriate types before calling). Do you know any reasonable solution? It can also be illustrated with C++ LLVM api, because llvm-py is very similar.
Indeed, IRBuilder does not expose an interface to do that, but you can create it manually - e.g. by using the constructors of GlobalVariable. You can store all the pointers in an array using conversion constant expressions, i.e. by generating:
#global = global [4 x i64*] [
i64* bitcast (void()* #f to i64*),
i64* bitcast (float(i32)* #g to i64*),
...
]
So, use ConstantExpr::getBitCast() to generate the casts from the Function to the array element type (which should preferrably be a pointer, I don't see the advantage in storing an i64). Then create a new GlobalVariable in the module and initialize it with all the constant expressions you've created.

Instance of a C++ vector in python (for TTrees in pyROOT)

I am trying to make a filter for a TTree (a ROOT object) in python using pyROOT. I have getting information from a TTree with several branches, some of which are C++ type vector<int>, vector<float> or vector<string>'s.
In order to pass information into a new tree, I need to access that from the old tree, I need to pass the address of a vector etc to the tree, which is then populated. To do this I need access to the address of such a new vector. This is quite easy in C++, but after looking at Cython and boost, I am unable to work it out. Ultimately I would like something like:
cppintvectorinpython = getcppintvector()
oldtree.setbranchaddress(branchname,cppintvectorinpython)
Is this possible?
CINT exports a number of STL classes for you, among them std::vector. To create e.g. a std::vector<double> from pyROOT do
import ROOT as r
vec = r.vector('double')()
Setting the branch address of the TTree is then pretty transparent due to pyROOT, e.g. you don't need to use pointers
tree = r.gDirectory.Get('oldtree')
tree.SetBranchAddress("vec_branch_name", vec)

Categories