Saturday, March 1, 2014

Papers for Sports Tracking

1. Camshift Tracking
https://code.google.com/p/camshift-kalman-examples/downloads/list
http://shelf3d.com/a3PtqeHFtU4#Image Processing CAMSHIFT algorithm

2. Camshift Tracking good example of tracking
http://www.youtube.com/watch?v=gE6uc1uc2Nw

3. Real-Time Tracking using OpenCV with color
http://www.youtube.com/watch?v=bSeFrPrqZ2A

4.Real-Time Tracking using OpenCV without color
http://www.youtube.com/watch?v=X6rPdRZzgjg

5. Pedestrian Detection using OpenCV
http://www.youtube.com/watch?v=AKLEuAtFDXQ

Tuesday, February 25, 2014

Interesting Vision Blogs

1. Driver Drowsiness detection
https://marcosnietoblog.wordpress.com/page/2/

2. Background subtraction and vehicle detection using opencv code
http://mateuszstankiewicz.eu/?p=189

3. Lots of interesting projects
http://www.potucek.net/projects.html
#include<opencv2/opencv.hpp> -- contains header for all opencv files

3. OpenCV Enthusiast
http://feelmare.blogspot.com/2012/10/optical-flow-sample-source-code-using.html

4. Learn OpenCV by examples
http://opencvexamples.blogspot.com/2013/10/fitting-rotated-boxes-and-ellipses-for.html#.UxIR0_ldV0w

5. OpenCV C++
http://opencv-srf.blogspot.com/p/opencv-c-tutorials.html

Tuesday, February 11, 2014

HIstogram Equalization

Great Tutorial on Histogram Equalization is found here

http://www.cs.utah.edu/~sujin/courses/reports/cs6640/project2/bhisteq.html

Saturday, January 25, 2014

Image Rotation Algorithm

It turned out to be trickier than I thought....why???

Rotation Matrix = [cos(t) sin(t); -sin(t) cos(t)]. Rotation Matrix tells where the new position of current pixel.

Although this method can be used for rotating image. Couple of problems
1) The pixel may be out of boundaries of the image
2) Sub-optimal results (pixellation)

A better approach is to think about the problem in reverse. For example, what would be the pixels in input image which contribute to the a pixel in output image. To find the answer, we have to invert rotation matrix.

The rotation matrix might give fractional pixels. For example (1,2) in output pixel might be equivalent to
(100.1, 20.1) in input image. One option would be to find nearest neighbour. The other option would be to use interpolation techniques such as bilinear interpolation etc.,


#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>

#include <iostream>
#include <iomanip>
#include <cassert>

using namespace cv;
enum interp
{
    nearest,
    bilinear
};
Mat rotateImage(const Mat source, double angle,int border=20);
cv::Mat imageRotate(const cv::Mat source, float angle, interp interp_type= nearest);
inline float bilinear_interp(cv::Mat source, const float& row, const float& col);

int main()
{
    //Read Image from a file
    const string foldername = "C:/Users/kvemishe/Documents/Vision/coursera/images/standard_test_images";
    const string filename   = "/lena_color_256.tif";
    string fullname = foldername+filename;
    Mat image = imread(foldername+filename,0);
    if (!image.data)
    {
        std::cout <<"Error reading file \n";
        getchar();
        exit(0);
    }
    imshow("Raw Image from file", image);
    const int angle = 15;
    int vangle = abs(angle)%90;
    float t = vangle * 3.14/ 180;
    int x = image.rows; int y = image.cols;
    float xborder = 0.5*( (cos(t)-1) * x + y * sin(t));
    float yborder = 0.5*( (cos(t)-1) * y + x * sin(t)); 
    std::cout << "xborder is " << xborder << std::endl;
    std::cout << "yborder is " << yborder << std::endl;
    int border = std::max(xborder,yborder);
    /*
    Mat rimage = rotateImage(image,angle,0);
    Mat rimage2 = rotateImage(image,angle,border);

    imshow("Rotated Image without border",rimage);
    imshow("Rotated Image with border",rimage2);
    */
    Mat rim = imageRotate(image,angle);
    imshow("No Interp", rim);

    Mat rim_interp = imageRotate(image,angle, bilinear);
    imshow("Interp", rim_interp);

    imwrite("rawimage.jpg", image);
    imwrite("RotatedImage_nointerp.jpg", rim);
    imwrite("RotatedImage_bilinearinterp.jpg", rim_interp);


    waitKey(0);
}

//Rotate using OpenCV
Mat rotateImage(const Mat source, double angle,int border, enum interp)
{
    Mat bordered_source;
    int top,bottom,left,right;
    top=bottom=left=right=border;
    copyMakeBorder( source, bordered_source, top, bottom, left, right, BORDER_CONSTANT,cv::Scalar() );
    Point2f src_center(bordered_source.cols/2.0F, bordered_source.rows/2.0F);
    Mat rot_mat = getRotationMatrix2D(src_center, angle, 1.0);
    Mat dst;
    warpAffine(bordered_source, dst, rot_mat, bordered_source.size());  
    return dst;
}

//Rotate using an algorithm
cv::Mat imageRotate(const cv::Mat source, float angle, interp interp_type)
{
    assert(source.rows >0 && source.cols >0);
    //Create Output image space
    int nRows = source.rows; int nCols = source.cols;
    cv::Mat dst(nRows, nCols,source.type(),cv::Scalar());

    int ci, cj;            //pixel location w.r.t center
    float t, si, sj;    //source pixels required for destination pixel

    //Convert angle from degrees to radians
    t = angle /180 * 3.1412;
    for (int i=0; i < nRows ; i++)
    {
        for (int j=0; j < nCols;j++)
        {
            //Bring the co-ordinate system to center of image as we will perform rotation w.r.t center
            ci = nRows/2 -i; cj= nCols/2-j;

            //Get the pixels from source image for corresponding rotation
            si =    cos(t)* ci  + sin(t) * cj;
            sj =    -sin(t) * ci + cos(t) * cj;

            //Convert the source pixel location to original co-ordinate system
            si = nRows/2-si; sj = nCols/2-sj;

            //Some source pixels might be out of the image, check if they are with in image borders
            if (si >0 && ceil(si) <nRows && sj >0 && ceil(sj) <nCols)
            {
                switch(interp_type)
                {
                case nearest:
                    dst.at<uchar>(i,j) = source.at<uchar>(si,sj); //using nearest neighbor
                    break;
                case bilinear:
                    dst.at<uchar>(i,j) = bilinear_interp(source,si,sj);
                    break;
                }
            }


        }
    }
    return dst;
}


inline float bilinear_interp(cv::Mat source, const float& row, const float& col)
{
    int loRow = floor(row);
    int hiRow = ceil(row);

    int loCol = floor(col);
    int hiCol  = ceil(col);

    //Perform Interpolation for column point along two rows
    //Row1 Interpolation
    float row1val = (hiCol - col) *source.at<uchar>(loRow,loCol) + (col - loCol) *source.at<uchar>(loRow,hiCol);

    //Row2 Interpolation
    float row2val = (hiCol - col) *source.at<uchar>(hiRow,loCol) + (col - loCol) *source.at<uchar>(hiRow,hiCol);

    //Perform final interpolation for required row
    float finalval = (hiRow - row)* row1val + (row-loRow) * row2val;

    return finalval;
}

Tuesday, December 3, 2013

Cameralink details

Details of Cameralink can be found here:
http://www.volkerschatz.com/hardware/clink.html

Cameralink cable extender
http://www.networkcable.com/PDF/BITMAXX_EQCL_3-19-09.pdf

http://forums.xilinx.com/t5/Spartan-Family-FPGAs/LVDS-SERDES-in-Spartan6-Camera-Link-or-DDR-style/td-p/313871

http://forums.xilinx.com/t5/Virtex-Family-FPGAs/camera-link-implementation-on-V-5/m-p/120150#M8821

http://www.xilinx.com/support/documentation/application_notes/xapp1071_V6_ADC_DAC_LVDS.pdf

Sunday, December 1, 2013

Image Processing Courses

1. Stanford Course CS448F (HWs in C++)
http://www.stanford.edu/class/cs448f/

2. Purdue Course EE367 Video Lectures
https://engineering.purdue.edu/~bouman/ece637/

3. Image Processing Course at Utah
http://www.eng.utah.edu/~cs6640/
Video Lectures:

4. Pattern Recognition Class
http://www.youtube.com/playlist?list=PLuRaSnb3n4kRDZVU6wxPzGdx1CN12fn0w

5. Image Analysis Class
http://www.youtube.com/playlist?list=PLuRaSnb3n4kSgSV35vTPDRBH81YgnF3Dd