This is a simple program that implements Augmented Reality in OpenCV. This is a follow-up for the previous post that was implemented in the old 1.0 API.
Files:
Download from DsynFLO box folder - https://app.box.com/s/nh82nmjt2w3fxj85g399
Usage:
Overlay Image:
Photo by Bharath P. Zero License.
Pattern:
Source:
Files:
Download from DsynFLO box folder - https://app.box.com/s/nh82nmjt2w3fxj85g399
Usage:
cmake . make ./app
Overlay Image:
Photo by Bharath P. Zero License.
Pattern:
Source:
//______________________________________________________________________________________ // Program : SimplAR 2 - OpenCV Simple Augmented Reality Program with Chessboard // Author : Bharath Prabhuswamy //______________________________________________________________________________________ #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; #define CHESSBOARD_WIDTH 6 #define CHESSBOARD_HEIGHT 5 //The pattern actually has 6 x 5 squares, but has 5 x 4 = 20 'ENCLOSED' corners int main ( int argc, char **argv ) { Mat img; Mat display = imread("shingani.jpg"); VideoCapture capture(0); Size board_size(CHESSBOARD_WIDTH-1, CHESSBOARD_HEIGHT-1); vector<Point2f> corners; if(display.empty()) { cerr << "ERR: Unable to find overlay image.\n" << endl; return -1; } if ( !capture.isOpened() ) { cerr << "ERR: Unable to capture frames from device 0" << endl; return -1; } int key = 0; while(key!='q') { // Query for a frame from Capture device capture >> img; Mat cpy_img(img.rows, img.cols, img.type()); Mat neg_img(img.rows, img.cols, img.type()); Mat gray; Mat blank(display.rows, display.cols, display.type()); cvtColor(img, gray, CV_BGR2GRAY); bool flag = findChessboardCorners(img, board_size, corners); if(flag == 1) { // This function identifies the chessboard pattern from the gray image, saves the valid group of corners cornerSubPix(gray, corners, Size(11,11), Size(-1,-1), TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1)); vector<Point2f> src; // Source Points basically the 4 end co-ordinates of the overlay image vector<Point2f> dst; // Destination Points to transform overlay image src.push_back(Point2f(0,0)); src.push_back(Point2f(display.cols,0)); src.push_back(Point2f(display.cols, display.rows)); src.push_back(Point2f(0, display.rows)); dst.push_back(corners[0]); dst.push_back(corners[CHESSBOARD_WIDTH-2]); dst.push_back(corners[(CHESSBOARD_WIDTH-1)*(CHESSBOARD_HEIGHT-1)-1]); dst.push_back(corners[(CHESSBOARD_WIDTH-1)*(CHESSBOARD_HEIGHT-2)]); // Compute the transformation matrix, // i.e., transformation required to overlay the display image from 'src' points to 'dst' points on the image Mat warp_matrix = getPerspectiveTransform(src, dst); blank = Scalar(0); neg_img = Scalar(0); // Image is white when pixel values are zero cpy_img = Scalar(0); // Image is white when pixel values are zero bitwise_not(blank,blank); // Note the jugglery to augment due to OpenCV's limitation passing two images of DIFFERENT sizes while using "cvWarpPerspective" warpPerspective(display, neg_img, warp_matrix, Size(neg_img.cols, neg_img.rows)); // Transform overlay Image to the position - [ITEM1] warpPerspective(blank, cpy_img, warp_matrix, Size(cpy_img.cols, neg_img.rows)); // Transform a blank overlay image to position bitwise_not(cpy_img, cpy_img); // Invert the copy paper image from white to black bitwise_and(cpy_img, img, cpy_img); // Create a "hole" in the Image to create a "clipping" mask - [ITEM2] bitwise_or(cpy_img, neg_img, img); // Finally merge both items [ITEM1 & ITEM2] } imshow("Camera", img); key = cvWaitKey(1); } destroyAllWindows(); return 0; }
No comments:
Post a Comment