Pages

Friday, December 19, 2014

Android Studio was unable to find a valid JVM

I obtained the following message when opening Android Studio 1.0.1 on Mac OSX Yosemite:
Android Studio was unable to find a valid JVM
Among some workarounds for the problem that I found in this Stackoverflow thread, I think the simplest one is by creating a small bash script that export the environment variable for the JVM and launch the Android Studio. For example, in my machine the JVM is located at /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk, so the script looks like this:
#!/bin/bash export STUDIO_JDK=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk open /Applications/Android\ Studio.app


That's all :)

Sunday, March 16, 2014

Kinect v2 developer preview + OpenCV 2.4.8: depth data

This time, I'd like to share code on how to access depth data using the current API of Kinect v2 developer preview using a simple polling, and display it using OpenCV. Basically the procedure is almost the same with accessing color frame.

In the current API, depth data is no longer mixed with player index (called body index in Kinect v2 API).

Disclaimer:
This is based on preliminary software and/or hardware. Software, hardware, APIs are preliminary and subject to change.
//Disclaimer:
//This is based on preliminary software and/or hardware, subject to change.

#include <iostream>
#include <sstream>

#include <Windows.h>
#include <Kinect.h>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/contrib/contrib.hpp>

inline void CHECKERROR(HRESULT n) {
    if (!SUCCEEDED(n)) {
        std::stringstream ss;
        ss << "ERROR " << std::hex << n << std::endl;
        std::cin.ignore();
        std::cin.get();
        throw std::runtime_error(ss.str().c_str());
    }
}

// Safe release for interfaces
template
inline void SAFERELEASE(Interface *& pInterfaceToRelease) {
    if (pInterfaceToRelease != nullptr) {
        pInterfaceToRelease->Release();
        pInterfaceToRelease = nullptr;
    }
}

IDepthFrameReader* depthFrameReader = nullptr; // depth reader

void processIncomingData() {
    IDepthFrame *data = nullptr;
    IFrameDescription *frameDesc = nullptr;
    HRESULT hr = -1;
    UINT16 *depthBuffer = nullptr;
    USHORT nDepthMinReliableDistance = 0;
    USHORT nDepthMaxReliableDistance = 0;
    int height = 424, width = 512;

    hr = depthFrameReader->AcquireLatestFrame(&data);
    if (SUCCEEDED(hr)) hr = data->get_FrameDescription(&frameDesc);
    if (SUCCEEDED(hr)) hr = data->get_DepthMinReliableDistance(
        &nDepthMinReliableDistance);
    if (SUCCEEDED(hr)) hr = data->get_DepthMaxReliableDistance(
        &nDepthMaxReliableDistance);

    if (SUCCEEDED(hr)) {
            if (SUCCEEDED(frameDesc->get_Height(&height)) &&
            SUCCEEDED(frameDesc->get_Width(&width))) {
            depthBuffer = new UINT16[height * width];
            hr = data->CopyFrameDataToArray(height * width, depthBuffer);
            if (SUCCEEDED(hr)) {
                cv::Mat depthMap = cv::Mat(height, width, CV_16U, depthBuffer);
                cv::Mat img0 = cv::Mat::zeros(height, width, CV_8UC1);
                cv::Mat img1;
                double scale = 255.0 / (nDepthMaxReliableDistance - 
                    nDepthMinReliableDistance);
                depthMap.convertTo(img0, CV_8UC1, scale);
                applyColorMap(img0, img1, cv::COLORMAP_JET);
                cv::imshow("Depth Only", img1);
            }
        }
    }
    if (depthBuffer != nullptr) {
        delete[] depthBuffer;
        depthBuffer = nullptr;
    }
    SAFERELEASE(data);
}

int main(int argc, char** argv) {
    HRESULT hr;
    IKinectSensor* kinectSensor = nullptr;     // kinect sensor

    // initialize Kinect Sensor
    hr = GetDefaultKinectSensor(&kinectSensor);
    if (FAILED(hr) || !kinectSensor) {
        std::cout << "ERROR hr=" << hr << "; sensor=" << kinectSensor << std::endl;
        return -1;
    }
    CHECKERROR(kinectSensor->Open());

    // initialize depth frame reader
    IDepthFrameSource* depthFrameSource = nullptr;
    CHECKERROR(kinectSensor->get_DepthFrameSource(&depthFrameSource));
    CHECKERROR(depthFrameSource->OpenReader(&depthFrameReader));
    SAFERELEASE(depthFrameSource);

    while (depthFrameReader) {
        processIncomingData();
        int key = cv::waitKey(10);
        if (key == 'q'){
            break;
        }
    }

    // de-initialize Kinect Sensor
    CHECKERROR(kinectSensor->Close());
    SAFERELEASE(kinectSensor);
    return 0;
}
Results in my messy room:

If we modify the scaling, for example:
                nDepthMaxReliableDistance = 900;
                nDepthMinReliableDistance = 500;
                int i, j;
                for (i = 0; i < height; i++) {
                    for (j = 0; j < width; j++) {
                        UINT16 val = depthMap.at<UINT16>(i,j);
                        val = val - nDepthMinReliableDistance;
                        val = (val > nDepthMaxReliableDistance ? 
                            nDepthMinReliableDistance : val);
                        val = (val < 0 ? 0 : val);
                        depthMap.at<UINT16>(i,j) = val;
                    }
                }

                double scale = 255.0 / (nDepthMaxReliableDistance - 
                    nDepthMinReliableDistance);
                depthMap.convertTo(img0, CV_8UC1, scale);
                applyColorMap(img0, img1, cv::COLORMAP_WINTER);
                cv::imshow("Depth Only", img1);
It may look like this:
That's all :)

Thursday, March 13, 2014

Kinect v2 developer preview + OpenCV 2.4.8: grab the color frame to OpenCV Mat

I am quite lucky that I could participate in the Kinect V2 developer preview program. :) Here, I'd like to share a simple code to grab color frame from the Kinect v2 sensor and convert it to OpenCV Mat format.

Disclaimer:
This is based on preliminary software and/or hardware. Software, hardware, APIs are preliminary and subject to change.
//Disclaimer:
//This is based on preliminary software and/or hardware, subject to change.

#include <iostream>
#include <sstream>

#include <Windows.h>
#include <Kinect.h>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

inline void CHECKERROR(HRESULT n) {
    if (!SUCCEEDED(n)) {
        std::stringstream ss;
        ss << "ERROR " << std::hex << n << std::endl;
        std::cin.ignore(); 
        std::cin.get();
        throw std::runtime_error(ss.str().c_str());
    }
}

// Safe release for interfaces
template<class Interface>
inline void SAFERELEASE(Interface *& pInterfaceToRelease) {
    if (pInterfaceToRelease != nullptr) {
        pInterfaceToRelease->Release();
        pInterfaceToRelease = nullptr;
    }
}

IColorFrameReader* colorFrameReader = nullptr; // color reader

void processIncomingData() { 
    IColorFrame *data = nullptr;
    IFrameDescription *frameDesc = nullptr;
    HRESULT hr = -1;
    RGBQUAD *colorBuffer = nullptr;
 
    hr = colorFrameReader->AcquireLatestFrame(&data); 
    if (SUCCEEDED(hr)) hr = data->get_FrameDescription(&frameDesc);
    if (SUCCEEDED(hr)) {
        int height = 0, width = 0;
        if (SUCCEEDED(frameDesc->get_Height(&height)) && 
            SUCCEEDED(frameDesc->get_Width(&width))) {
            colorBuffer = new RGBQUAD[height * width];
            hr = data->CopyConvertedFrameDataToArray(height * width * sizeof(RGBQUAD),
                 reinterpret_cast<BYTE*>(colorBuffer), ColorImageFormat_Bgra);
            if (SUCCEEDED(hr)) {
                cv::Mat img1(height, width, CV_8UC4,
                    reinterpret_cast<void*>(colorBuffer));
                cv::imshow("Color Only", img1);
            }
        }
    }
    if (colorBuffer != nullptr) {
        delete[] colorBuffer;
        colorBuffer = nullptr;
    }
    SAFERELEASE(data);
}

int main(int argc, char** argv) {
    HRESULT hr;
    IKinectSensor* kinectSensor = nullptr;     // kinect sensor

    // initialize Kinect Sensor
    hr = GetDefaultKinectSensor(&kinectSensor);
    if (FAILED(hr) || !kinectSensor) {
        std::cout << "ERROR hr=" << hr << "; sensor=" << kinectSensor << std::endl;
        return -1;
    }
    CHECKERROR(kinectSensor->Open());

    // initialize color frame reader
    IColorFrameSource* colorFrameSource = nullptr; // color source
    CHECKERROR(kinectSensor->get_ColorFrameSource(&colorFrameSource));
    CHECKERROR(colorFrameSource->OpenReader(&colorFrameReader));
    SAFERELEASE(colorFrameSource);

    while (colorFrameReader) {
        processIncomingData();
        int key = cv::waitKey(10);
        if (key == 'q'){
            break;
        }
    }
 
    // de-initialize Kinect Sensor
    CHECKERROR(kinectSensor->Close());
    SAFERELEASE(kinectSensor);
    return 0;
}
That's all :)

Thursday, December 26, 2013

Files does not sync on shared folder VMWare Player

Since my Parallels software is not compatible with Mavericks, I decided to use Windows machine for virtualization. On Windows, I am using VMWare Player to run Linux occasionally. Recently, I often use the VMWare since the software that I am using is only available on Linux.

I found that using the latest VMWare tools (as this article is written), the files on shared folders are out of sync if they are modified from the host (Windows 7). After searching for the solutions, I found the discussions on the VMWare communities forum here: https://communities.vmware.com/message/2313778.

It seems that VMWare teams are still addressing the issues (as this article is written). Meanwhile, the solution is to revert back to older version of VMWare tools.

Here is the steps:
  1. Before turning on the VMWare, modify the VMWare file .vmx setting, otherwise, the downgrade can be overridden:
    tools.upgrade.policy = "manual"
  2. As super user, unmount the current shared folder. Example:
    # umount /mnt/hgfs
  3. Download the older version of the VMWare tool here (select the appropriate one based on the OS):
    https://softwareupdate.vmware.com/cds/vmw-desktop/fusion/6.0.1/1331545/packages/
    In my case, I downloaded com.vmware.fusion.tools.linux.zip.tar.
  4. Extract the file. If you are using linux, extract linux.iso file as well or just mount it.
  5. using super user, execute the vmware install script:
    # ./vmware-install.pl
  6. After completed, make sure the build version is build-1294478:
    root@ubuntu:~# vmware-toolbox-cmd -v
    9.6.0.26048 (build-1294478)
    

That's all :)

Thursday, October 10, 2013

Parallels 7 cannot install Ubuntu 13.04 with error: Soft lockup

Today I tried to install Ubuntu 13.04 on Parallels 7. But when booting using the installation disk, I got error message about Soft lockup.

Seems that the solution is very straightforward: remove the tick on the "Show battery in Linux" from the dialog of Options > Optimizations.

Credit to the thread from here. That's all :)

Monday, July 01, 2013

How to have a similar mouse acceleration on Mac OSX with Windows

Have you ever noticed that the movement of mouse pointer on Mac OSX is somewhat different from that of on Windows?

Before I started using Mac OSX around 3 years ago, I have been a heavy user of Windows and Linux for years. Probably this is just my personal preference, but I feel that the acceleration of mouse movement on Mac OSX is not as comfortable as on Windows. I have been looking for the solution to get the same acceleration "feel" ever since but found nothing comparable to Windows. I have tried several software that can control mouse acceleration on Mac OSX, but still not satisfied. Even there are lengthy discussion on Apple forum debating this matter.

Gladly, there are wonderful engineers that started to develop the promising solution: http://smoothmouse.com/

If anyone feel uncomfortable with the acceleration of mouse on Mac OSX, I would suggest to try this software. It surpasses any other softwares (includes the paid one) that I have tried to make my mouse movement on Mac OSX as similar as on Windows. I hope that Apple could notice this little yet important matter, especially for new users who were heavy users of Windows, and provide built-in solution on the next release of OSX. I could understand that not all users notice the difference. But It is somewhat a shame on Apple for not noticing this little matters for years.

That's all :)

Friday, March 15, 2013

WinShell cannot start AcrobatReader XI

When I tried to launch Acrobat Reader from WinShell, I got the following error message:
Cannot start AcrobatReader or open the document.
1. Please check on the exe file and cmd line of the PDFView options.
2. Please set correct Adobe DDE Version in registry key 'HKEY_CLASSES_ROOT\acrobat\shell\open\ddeexec\application'
Seems that the solution is quite straightforward:
  1. Make sure the Acrobat Reader is already running before calling it from WinShell (just run the Acrobat Reader from the start menu once, and keep it running).
  2. Edit the registry entry as mentioned in the error message. For example, in my case, I found that the value of my Acrobat Reader was set to AcroViewR10. Since I am using version 11, I have to change the value to AcroViewR11.
That's all :)