Tuesday, February 26, 2013

OpenCV combine two images

In computer vision community, developer always face one basic task to visualize the correspondences between two frames, and the easier solution might be combine two images into one single image.

In this blog, I will give a convenient and easy to understand solution to solve this problem. Of course, so far, this is just a simple starting point, you could extent it to make more robust.

The code would be as follow:


struct myexception : public std::exception{
    std::string s;
    myexception(std::string ss):s(ss){}
    virtual const char* what() const throw() {return s.c_str();}
    ~myexception() throw(){}
};



// combine two identical size images into one big image
void combineTwoImages(cv::Mat &dst, const cv::Mat img1, const cv::Mat img2){
    if (img1.cols != img2.cols || img1.rows != img2.rows) {
        throw myexception("img1 and img2 should be identical size");
    }
    int rows = img1.rows;
    int cols = img1.cols;
    dst = cvCreateMat(rows, 2 * cols, img1.type());
    cv::Mat tmp = dst(cv::Rect(0, 0, cols, rows));
    img1.copyTo(tmp);
    tmp = dst(cv::Rect(cols, 0, cols, rows));
    img2.copyTo(tmp);
}


As you could notice, this code would only work for identical size case, you would extent it to handle two arbitrary size images as well.

PS: cv::Rect(x, y, _width, _height)

Hope this would be helpful.

Install PCL and first project in XCode

PCL (Point Cloud Library) is getting more popular these days. It's good for Kinect users and might be also helpful for visualization usages as well.

I used to attempt to install the PCL, couple months ago, however at that time it's not very successful. This time, it works. For my record and for others who may interested, I will list the details below.

1. Following the instruction in: http://pointclouds.org/documentation/tutorials/compiling_pcl_macosx.php#compiling-pcl-macosx
till installing Qhull.
2. Install and download libusb, openNI and sense from the following webpage ( do not install libusb from macports):
http://pointclouds.org/downloads/macosx.html
3. Build PCL as the instruction in Step 1 webpage.

The first project in Xcode:

0.1 Switch Compiler for C/C++/Objective-C from Apple LLVM compiler 4.2 -> LLVM GCC 4.2

1. adding the following entries into "Header Search Paths"
1.1 /usr/local/include/pcl-1.7
1.2 /opt/local/include
1.3 /opt/local/include/eigen3
1.4 /opt/local/include/vtk-5.10



2. Adding "New Group", named: boost, right-click new created "boost" folder, and Add File to project:
locate file: /opt/local/lib/libboost_system-mt.dylib

3. Adding "New Group", named: pcl, right-click new created "pcl" folder, and Add File to project:
locate file: ($whereBuildPCL)/build/lib/libpcl_io.1.7.0.dylib, and ($whereBuildPCL)/build/lib/libpcl_common.1.7.0.dylib

4. input the following script into main.cpp


#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int main(int argc, const char * argv[])
{
    pcl::PointCloud<pcl::PointXYZ> cloud;
    // fill in the cloud data
    cloud.width = 5;
    cloud.height = 1;
    cloud.is_dense = false;
    cloud.points.resize(cloud.width * cloud.height);
    
    for (size_t i = 0; i < cloud.points.size(); ++i){
        cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
    }
    
    pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);
    std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;
    
    for (size_t i = 0; i < cloud.points.size(); ++i)
        std::cerr << "   " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;
    
    return 0;
}

5. Find out the output .pcd file 
5.1 Open Organizer: (Window->Organizer)
5.2 find your Projects, right click the right arrow next to your "Derived Data"
5.3 Build/Products/Debug/test_pcd.pcd


Saturday, February 23, 2013

OpenCV: compare whether two Mat is identical

As MATLAB users could always conveniently compare two matrix, in order to decide whether the two matrix is identical or not.
However, in OpenCV this easy task is not straight forward as you first thought.
The underlying small openCV script could help you to address this simple task.

// return true if two matrix is identical, false otherwise


bool BasicUtil::matIsEqual(const cv::Mat mat1, const cv::Mat mat2){
    // treat two empty mat as identical as well
    if (mat1.empty() && mat2.empty()) {
        return true;
    }
    // if dimensionality of two mat is not identical, these two mat is not identical
    if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims) {
        return false;
    }
    cv::Mat diff;
    cv::compare(mat1, mat2, diff, cv::CMP_NE);
    int nz = cv::countNonZero(diff);
    return nz==0;
}


PS: I'm currently building a C++ toolbox in order to replace some basic MATLAB functionality for computer vision users. I will release it once I built a considerable functionalities.

prettify