Tracking down BadImageFormatException in C#

I know It’s been quite some time since my last post, but what can I say? I’ve been quite busy 🙂 Here is the latest issue that I got stuck on for a few hours, and I thought I’d share what worked in the end.

I was working on a large C# project that had a lot of dependencies on native C++ DLLs in Visual Studio 2015. I had compiled all the 3rdparty dependencies to DLLs myself and had included them in the C# project. On my main development machine, everything was working fine, but I couldn’t get the project to work on another machine with a clean Windows 10 install. The project would compile fine but would fail to run with BadImageFormatException.

From prior experience, I knew this error had to do with a mismatch between dependency architectures somewhere (e.g. 32 bit binary is trying to load a 64 bit binary or vice versa). However, this time I was so sure that wasn’t the case because I had built almost all the DLL dependencies myself and I knew that everything was built in x64 mode. Also, it was working fine on my development machine.

After a few hours of frustration and using the Fuslogvw.exe tool without obtaining much more insight about the problem, I decided to use Dependency Walker to see what’s happening. This great little tool did magic! I noticed that one of the dependencies that I hadn’t built myself was actually a 32-bit binary. The reason this was not causing an issue on my development machine was that as bad luck would have it, the 64-bit version of that dependency was in my PATH variable on that machine, so my C# project would load up the correct DLL. However, on other machines with a clean Windows installation, this wasn’t the case and because the only found binary was the 32-bit version, I would receive that dreaded BadImageFormatException.

librealsense with ARM support

Recently, I was able to successfully use RealSense R200 on my NVIDIA Jetson TX1 with librealsense. I had to replace some SSSE3 instructions in the code to get it to compile under ARM. I created a fork of librealsense on Github with all the changes I made. Check it out here: ttps://github.com/Maghoumi/librealsense

R200 works at 60 FPS with my Jetson TX1 flawlessly! 🙂

Create Bootable USB Flash Drive from ISO Image (with UEFI Support)

Update: If you’re looking for Windows 10 UEFI installation, take a look at the addendum at the end of the post!

Although there are a lot of applications for creating a bootable flash drive using an ISO image (such as UNetBootin), not many of them support the creation of a bootable flash drive that can be used for installing the operating system in UEFI mode (I’ve never succeeded with UNetBootin personally!).

There is a comprehensive guide about installing Linux in UEFI mode that details all the do’s and don’ts. Most of us are already familiar with all the necessary steps but the creation of a bootable UEFI compatible flash drive from an ISO file 😀 . There are two ways to create a UEFI compatible flash drive:

TL;DR

There is a great application called rufus that does the trick for you. You can find it here. The good thing about this app is that the USB flash drive will end up with a single partition and is still usable in Windows.

TL;WR

(That’s Too Long; Wanna Read; for the lack of a better acronym!)

The other possibility is to use the good ol’ Linux utility disk dump ( dd). dd It should be already available under any Linux installation. It is also available under Windows if you have Cygwin installed. The procedure is as follows.

WARNING: You will loose all the data on your flash drive.

NOTE: If you’re using Cygwin, make sure to run Cygwin as Administrator (right click, run as Administrator).

  1. Insert the flash drive and determine what device it has been mapped to by running.
    cat /proc/partitionsThis should output a list of partitions in /dev. The devices and the partitions are numbered. Since you want to work directly with the whole drive, ignore the numbers at the end. In my case, I found out that my flash drive was mapped to /dev/sde (by observing two entries in the list: /dev/sde and /dev/sde1). Make sure you select the correct partition otherwise you’ll ruin another storage device.
  2. Dump the ISO file to the device you noted in step 1:
    dd if=/path/to/your/image.iso of=[the device above] bs=4MIn my case it was:
    dd if=~/image.iso of=/dev/sde bs=4M

This will start dumping the image onto the flash drive. You won’t get any output from the command while the operation is in progress. To check the progress, you need to open another terminal (command) window, determine the PID of dd process by running ps -e (which will give you PID), and then running the command kill -USR1 [PID]; sleep 1; to see the output of dd in the original terminal (command) window.

After the operation has completed, you can boot the flash drive in UEFI mode. The flash drive is booted in UEFI mode if the output of the following command is a list of files:

ls /sys/firmware/efi

Hopefully, the next time I want to install a Linux distro in UEFI mode, I wouldn’t have to Google for two hours.

Addendum

Unsurprisingly, rufust can also be used for Windows 10 UEFI installation. Unfortunately, I didn’t have much luck with Microsoft’s media creation tool. I used it at first, yet I was getting the black screen which says the installation cannot continue (wish I had taken a note of what it said exactly).

Nevertheless, installation with rufus went smoothly. Here’s a direct link to Windows 10 ISO (link courtesy of Reddit). Grab the image, run rufus, select GPT Partition Scheme for UEFI, file system MUST be FAT32 (I chose the block size of 8192, anything other than FAT32 did not boot for me). Click start and you’re golden 🙂 I also had CSM enabled in my bios settings. Not sure if that really mattered though!

UPDATE: I noticed that the above settings had to be slightly different if the goal was an MBR/BIOS installation. What I had to do was to select “MBR Partition Scheme for BIOS or UEFI-CSM“, and the file system must have been NTFS. Also, I had to completely disable secure boot in the BIOS settings to get the flash drive too boot up.

 

Align Depth and Color Frames – Depth and RGB Registration

Sometimes it is necessary to create a point cloud from a given depth and color (RGB) frame. This is especially the case when a scene is captured using depth cameras such as Kinect. The process of aligning the depth and the RGB frame is called “registration” and it is very easy to do (and the algorithm’s pseudo-code is surprisingly hard to find with a simple Google search! 😀 )

To perform registration, you would need 4 pieces of information:

  1. The depth camera intrinsics:
    1. Focal lengths fxd and fyd (in pixel units)
    2. Optical centers (sometimes called image centers) Cxd and Cyd
  2. The RGB camera intrinsics:
    1. Focal lengths fxrgb and fyrgb (in pixel units)
    2. Optical centers (sometimes called image centers) Cxrgb and Cyrgb
  3. The extrinsics relating the depth camera to the RGB camera. This is a 4×4 matrix containing rotation and translation values.
  4. (Obviously) the depth and the RGB frames. Note that they do not have to have the same resolution. Applying the intrinsics takes care of the resolution issue. Using camera’s such as Kinect, the depth values should usually be in meters (the unit of the depth values is very important as using incorrect units will result in a registration in which the colors and the depth values are off and are clearly misaligned).
    Also, note that some data sets apply a scale and a bias to the depth values in the depth frame. Make sure to account for this scaling and offsetting before proceeding. In order words, make sure there are no scales applied to the depth values of your depth frame.

Let depthData contain the depth frame and rgbData contain the RGB frame. The pseudo-code for registration in MATLAB is as follows:

function [aligned] = ...
                    depth_rgb_registration(depthData, rgbData,...
                    fx_d, fy_d, cx_d, cy_d,...
                    fx_rgb, fy_rgb, cx_rgb, cy_rgb,...
                    extrinsics)

    depthHeight = size(depthData, 1);
    depthWidth = size(depthData, 2);
    
    % Aligned will contain X, Y, Z, R, G, B values in its planes
    aligned = zeros(depthHeight, depthWidth, 6);

    for v = 1 : (depthHeight)
        for u = 1 : (depthWidth)
            % Apply depth intrinsics
            z = single(depthData(v,u)) / depthScale;
            x = single((u - cx_d) * z) / fx_d;
            y = single((v - cy_d) * z) / fy_d;
            
            % Apply the extrinsics
            transformed = (extrinsics * [x;y;z;1])';
            aligned(v,u,1) = transformed(1);
            aligned(v,u,2) = transformed(2);
            aligned(v,u,3) = transformed(3);
        end
    end

    for v = 1 : (depthHeight)
        for u = 1 : (depthWidth)
            % Apply RGB intrinsics
            x = (aligned(v,u,1) * fx_rgb / aligned(v,u,3)) + cx_rgb;
            y = (aligned(v,u,2) * fy_rgb / aligned(v,u,3)) + cy_rgb;
            
            % "x" and "y" are indices into the RGB frame, but they may contain
            % invalid values (which correspond to the parts of the scene not visible
            % to the RGB camera.
            % Do we have a valid index?
            if (x > rgbWidth || y > rgbHeight ||...
                x < 1 || y < 1 ||...
                isnan(x) || isnan(y))
                continue;
            end
            
            % Need some kind of interpolation. I just did it the lazy way
            x = round(x);
            y = round(y);

            aligned(v,u,4) = single(rgbData(y, x, 1);
            aligned(v,u,5) = single(rgbData(y, x, 2);
            aligned(v,u,6) = single(rgbData(y, x, 3);
        end
    end    
end

A few things to note here:

  1. The indices x and y in the second group of for loops may be invalid which indicates that the obtained RGB pixel is not visible to the RGB camera.
  2. Some kind of interpolation may be necessary when using x and y. I just did rounding.
  3. This code can be readily used with savepcd function to save the point cloud into a PCL compatible format.

The registration formulas were obtained from the paper “On-line Incremental 3D Human Body Reconstruction for HMI or AR Applications” by Almeida et al (2011). The same formulas can be found here. Hope this helps 🙂

 

C++ Function in Header throws Linker “already defined” Errors

If you define a function in the global namespace in a C++ header file and encounter linker errors (complaining about the function already defined elsewhere), there’s a simple fix! Simply mark the function as inline. This will prevent the duplication of the function in other source files.

Note that using inclusion guards does not solve this problem and you must define the function as inline.

CGAL Point in Polyhedron Algorithm

The “point in polygon” or “point in polyhedron” is a classic computer graphics problem. The goal is to determine whether a given point is inside a polygon (in 2D) or a polyhedron (in 3D).

One solution to the problem is shooting a ray originating from the said point to an arbitrary direction and determine the number of intersections of the ray with the polygon or polyhedron. If the ray intersects the shape an odd number of times, then the point is inside the shape. Otherwise it is outside the shape.

There are problems associated with this approach. An important edge case is when the point is on the surface of the shape. Also, it is commonly advisable to shoot multiple rays instead of just one, and then do a majority voting.

Luckily, in CGAL the point in polyhedron test is very simple and you don’t have to worry about the edge cases! You can do the test using the Side_of_triangle_mesh class. A code snippet is shown below:

 

#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/algorithm.h>
#include <CGAL/Side_of_triangle_mesh.h>

typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
typedef CGAL::Side_of_triangle_mesh<Polyhedron, K> Point_inside;

bool pointInside(Polyhedron &polyhedron, Point &query) {
    // Construct AABB tree with a KdTree
    Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron);
    tree.accelerate_distance_queries();
    // Initialize the point-in-polyhedron tester
    Point_inside inside_tester(tree);
    
    // Determine the side and return true if inside!
    return inside_tester(query) == CGAL::ON_BOUNDED_SIDE;
}

You can also determine whether the point is on the surface of the polyhedron or not.

Undo a Git Commit on GitHub

In case you’ve pushed an unwanted commit to GitHub (or any upstream Git repository), you can simply undo it. To do so, move the HEAD to the commit that you want to undo to and then run the following command:

git push -f origin HEAD^:master

Prevent Unity 3D Text from Always Appearing on Top while Maintaining Rich-Text Support

The TextMesh component in Unity has an annoyance which causes the text that it displays be rendered always on top. This is useful if you want your GUI elements to always appear on top but if you want to have a 3D text attached to a 3D object, this creates the weirdest results!

There’s already an entry in Unity’s wiki page detailing how the issue can be worked around using a custom shader. This YouTube video shows the application of the mentioned method (it’s quite useful even though the guy is speaking Russian!). Also, if you are not sure how a texture can be built using a font, follow the steps described in this awesome blog post.

The issue with the above method is that it messes with the rich text support of TextMesh. Essentially, all text will be rendered with the specified color of the created material. I found a better custom shader in the Unity 3D forum! This solved my z-depth issues.

SimpleScalar Installation Under Windows

Installing the SimpleScalar simulator is relatively straightforward under Linux. For Windows installation, the Cygwin toolchain is required. Grab the latest Cygwin installer (setup-x86_64) from here: https://cygwin.com/setup-x86_64.exe (note that this is intended for 64-bit machines).

After running the installer, just proceed through the wizard. The default installation directory is C:\cygwin64. When selecting a mirror website, usually mirrors.kernel.org is the fastest mirror. Select where you want the Cygwin packages to be installed. In the package installation window, select the following packages under Devel:

  1. gcc-core
  2. gcc-g++
  3. make

Also, under Web select the w3m package (this will make the download process much easier). The installer will say that additional dependencies are needed. Click “Yes” to install the additional dependency packages.

Note: To install a package, you can simply click on the circular arrows next to the name of the package. The text next to the arrow will cycle between “skip” and the desired version of the package. Feel free to install the latest available version of each of the packages above.

After the installation of Cygwin is finished, simply open a Cygwin bash terminal (by opening “Cygwin64 Terminal” from the installed programs in Start menu) and follow these steps (credits go to Ramya Pradhan):

  1. Download SimpleScalar:
     w3m http://www.simplescalar.com/agreement.php3?simplesim-3v0e.tgz
    Use the arrow keys to navigate to the bottom of the page to accept the terms. Move the cursor to ‘I Agree’ and hit enter. You will see a message ‘(Download) Save file to: simplesim-3v0e.tgz’ at the bottom of the page, hit enter to save file in the current directory. To get out of the browser, press q.
  2. Compile SimpleScalar
     tar xvzf simplesim-3v0e.tgz
     cd simplesim-3.0
     make config-pisa
     make
  3. Test the installation using
     ./sim-safe tests/bin.little/test-math

Installing SciPy, NumPy and matplotlib Under Cygwin

Today I tried installing these modules under Cygwin with pip. The whole thing took a few hours to figure out thanks to crappy bundled packages that pip fetches and lack of consistency between helps available online.

To install pip, you need to have `python3-setuptools`installed. Then using the `easy_install3 pip` command you can install pip.

After that, you need to have `liblapack-devel` and `libopenblas` installed via Cygwin’s package manager (SciPy depends on them). You also need to have `gcc-fortran`, `python-gtk2`, `tcl-tk`, `libpng`, `pkg-config` and a bunch of other stuff (that pip installer complains about) installed. The dependencies that pip complains about are straightforward (just mark them for installation in Cygwin’s installer).

Running `pip -v install numpy` and `pip -v install matplotlib` should get you those packages without much headache. The most important thing is that as of SciPy v 0.16.1, there seems to be some error in SciPy’s C files that prevents compilation and installation. I was able to get it to install using `pip -v install scipy==0.15.1`.

After installation, you may notice that you can’t plot stuff using mathplotlib’s `pyplot` module. To fix that, you need to have `XWinServer` running and should configure matplotlib to use `tkagg` backend. To do this, locate the file `matplotlibrc` and change `backend      : agg` to `backend      : tkagg`. The plots should show now!