tag:blogger.com,1999:blog-25869065174275619692024-02-19T07:20:34.702-08:00Haris's BlogUnknownnoreply@blogger.comBlogger4125tag:blogger.com,1999:blog-2586906517427561969.post-42303752328736651012013-05-03T05:27:00.003-07:002013-06-29T02:41:03.089-07:00Analog Clock Using OpenCV<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-size: small;">Here is a simple code that create an analog clock synchronized with system clock using OpenCV.</span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><br /> The idea is simple first we create an image of size 640X640 and draw second, minute and hour markings. These marking are drawn using OpenCV line and the co-ordinates are find-out using <a href="http://en.wikipedia.org/wiki/Circle#Equations" target="_blank">parametric equation of circle</a> <span style="color: black;"></span>. Before that we need to draw a circle from the centre of the image with a radius r=image->width/2=320;</span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: small;">The paramet<span style="font-size: small;">ric equation of a circle can be written as</span></span></div>
<div style="text-align: justify;">
<span style="font-size: small;"><span style="font-size: small;"> </span><br />x = cx + r * cos(a * CV_PI / 180.0)<br />y = cy + r * sin(a * CV_PI / 180.0) <br /><br />Where "cx" and "cy" are the <span style="font-size: small;">center</span> of image, "r" is the radius of circle, "a" is the angle.<br /><br /> As we know<span style="font-size: small;"> t</span>he hour hand of a normal 12-hour analogue clock turns 360° in 12 hours so angle between each marking will be 360/12=30 degree. As I said before our hour <span style="font-size: small;">markings</span> are just lines and we need to find co-ordinates of each line, so as a first step we will <span style="font-size: small;">find out</span> the inner co-ordinates of each line from <span style="font-size: small;">center</span>. For this just consider a circle with fixed radius r (less than image width/2) from <span style="font-size: small;">center</span>, and find out the <span style="font-size: small;">perimeter</span> <span style="font-size: small;">co-donates</span>(x,y) of the circle on each 30 degree, that is for <span style="font-size: small;">different</span> angle value(0,30,60...360) calculate x and y with fixed r </span><span style="font-size: small;"><span style="font-size: small;">u</span>sing</span><span style="font-size: small;"><span style="font-size: small;"> the above equation</span>. Then note down the values. Here I stored this value in an array h1[][]. Using the same method we can calculate the outer co-ordinates for hour marking by incrementing r with a constant. And stored this value in an array h2[][].<br /><br /> While in the case of minute hand 60 markings are there and each markings are seperted with 360/60=6 degree. So using the above equation we can calculate inner and outer co-ordinates for for minute markings. The only difference is that the angle should be incremanetd by 6 degree. Here I stored this values in s1[][] and s2[][].<span style="font-size: small;"> </span>After finding these co-ordinates just draw these lines to image in a for loop<span style="font-size: small;">.</span></span><br />
<br />
<span style="font-size: small;"><span style="font-size: small;"> The next thing we need to do is that update hour, minute and second hand with <span style="font-size: small;">system</span> time and of course these three are also OpenCV lines and these lines are start from <span style="font-size: small;">center</span> and the second <span style="font-size: small;">co-ordinates</span> will <span style="font-size: small;">change</span> according to system clock tick. So <span style="font-size: small;">before</span> doing these we need to back up the image we have drawn <span style="font-size: small;">because</span> on each clock tick we <span style="font-size: small;">don't</span> need to draw the hour, minute and second <span style="font-size: small;">markings</span>.<br /><br /> As a next step we will create a while loop and access <span style="font-size: small;">system</span> clock and store to a variable. Then we will convert all these value such as hour, minute and second to angle and display <span style="font-size: small;">in a window.</span><br /><br /> Using the above equation we will find out second co-ordinates for hour minute and second hand then draw these lines to the image. Finally using imshow <span style="font-size: small;">display</span> the image. And before entering to the while loop again we will clear the current image and clone from backup image. </span></span><br />
<span style="font-size: small;"><span style="font-size: small;"><br /></span></span>
<span style="font-size: small;"><span style="font-size: small;">Here is the full s<span style="font-size: small;"><span style="font-size: small;">ource</span> code.</span></span></span><br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><span style="font-size: small;"><span style="font-size: small;"><span style="font-size: small;"><pre class="brush:cpp">#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include <stdio.h>
#include <time.h>
#include <sys/timeb.h>
#include <sys/time.h>
using namespace std;
using namespace cv;
int main()
{
Mat clk(640,640,CV_8UC3); //Mat to store clock image
Mat back_up(640,640,CV_8UC3); //Mat to store backup image
Point cent(320,320);
Point perim(320,0);
int rad =320;
float sec_angle=270;
float min_angle=330;
float hour_angle=210;
//Draw second markings
int s1[60][2]={{320,25},{351,27},{381,31},{411,39},{440,51},{468,65},{493,81},{517,101},{539,123}, \
{559,147},{575,173},{589,200},{601,229},{609,259},{613,289},{615,320},{613,351},{609,381},{601,411}, \
{589,440},{575,468},{559,493},{539,517},{517,539},{493,559},{468,575},{440,589},{411,601},{381,609}, \
{351,613},{320,615},{289,613},{259,609},{229,601},{200,589},{173,575},{147,559},{123,539},{101,517}, \
{81,493},{65,468},{51,440},{39,411},{31,381},{27,351},{25,320},{27,289},{31,259},{39,229},{51,200}, \
{65,173},{81,147},{101,123},{123,101},{147,81},{172,65},{200,51},{229,39},{259,31},{289,27},};
int s2[60][2]={{320,5},{353,7},{385,12},{417,20},{448,32},{478,47},{505,65},{531,86},{554,109}, \
{575,135},{593,163},{608,192},{620,223},{628,255},{633,287},{635,320},{633,353},{628,385},{620,417}, \
{608,448},{593,478},{575,505},{554,531},{531,554},{505,575},{478,593},{448,608},{417,620},{385,628}, \
{353,633},{320,635},{287,633},{255,628},{223,620},{192,608},{163,593},{135,575},{109,554},{86,531}, \
{65,505},{47,478},{32,448},{20,417},{12,385},{7,353},{5,320},{7,287},{12,255},{20,223},{32,192}, \
{47,163},{65,135},{86,109},{109,86},{135,65},{162,47},{192,32},{223,20},{255,12},{287,7}};
for(int i=0;i<60;i++){
line(clk,Point(s1[i][0],s1[i][1]),Point(s2[i][0],s2[i][1]), Scalar(0,255,0,0), 1.5,CV_AA,0);
}
//Draw hour markings
int h1[12][2]={{320,45},{458,82},{558,183},{595,320},{558,458},{458,558},{320,595},{183,558}, \
{82,458},{45,320},{82,183},{182,82}};
int h2[12][2]={{320,5},{478,47},{593,163},{635,320},{593,478},{478,593},{320,635},{163,593}, \
{47,478},{5,320},{47,163},{162,47}};
for(int i=0;i<12;i++){
line(clk,Point(h1[i][0],h1[i][1]),Point(h2[i][0],h2[i][1]), Scalar(0,255,0,0), 4,CV_AA,0);
}
circle(clk,cent,rad-5,Scalar(0,0,255,0),4,CV_AA,0); //Dreaw outercircle of clock
circle(clk,cent,1,Scalar(0,255,0,0),5,CV_AA,0); //Draw inner circle
back_up=clk.clone(); // Clone to backup image
time_t rawtime;
struct tm * timeinfo;
float second;
float minute;
float hour;
float millisec;
struct timeb tmb;
while(1){
//Access system time and store to local variable
ftime(&tmb);
rawtime=tmb.time;
timeinfo = localtime ( &rawtime );
second = timeinfo->tm_sec;
minute = timeinfo->tm_min;
hour = timeinfo->tm_hour;
millisec = tmb.millitm;
second=second+millisec/1000;
sec_angle=(second*6)+270; //Convert second to angle
minute=minute+second/60;
min_angle=minute*6+270; //Conver minute to angle
if(hour>12)hour = hour-12;
hour_angle=(hour*30)+(minute*.5)+270; //Conver hour to angle
if(sec_angle>360)sec_angle=sec_angle-360;
if(min_angle>360)min_angle=min_angle-360;
if(hour_angle>360)hour_angle=hour_angle-360;
//Fond out the co-ordinates in the circle perimeter for second and draw the line from center
perim.x = (int)round(cent.x + (rad-5) * cos(sec_angle * CV_PI / 180.0));
perim.y = (int)round(cent.y + (rad-5) * sin(sec_angle * CV_PI / 180.0));
line(clk,cent,perim, Scalar(0,255,255,0), 1.5,CV_AA,0);
//Fond out the co-ordinates on the circle perimeter for minute and draw the line from center
perim.x = (int)round(cent.x + (rad-50) * cos(min_angle * CV_PI / 180.0));
perim.y = (int)round(cent.y + (rad-50) * sin(min_angle * CV_PI / 180.0));
line(clk,cent,perim, Scalar(0,255,255,0), 4,CV_AA,0);
//Fond out the co-ordinates on the circle perimeter for hour and draw the line from center
perim.x = (int)round(cent.x + (rad-75) * cos(hour_angle * CV_PI / 180.0));
perim.y = (int)round(cent.y + (rad-75) * sin(hour_angle * CV_PI / 180.0));
line(clk,cent,perim, Scalar(0,255,255,0), 8,CV_AA,0);
imshow("Clock",clk); //Show result in a window
clk.setTo(0); // set clk image to zero for next drawing
clk=back_up.clone(); // Clone the previously drawned markings from back-up image
char c=waitKey(10); // Wait for few millisecond and go back to loop.
if(c==27)break;
}
return 0;
}
</pre>
</span></span></span></pre>
</div>
<span style="font-size: small;"><span style="font-size: small;"><span style="font-size: small;">
</span></span></span><span style="font-size: small;"><span style="font-size: small;"><span style="font-size: small;"><iostream><stdio .h=""><time .h=""><sys timeb.h=""><sys time.h=""><!--12--><!--60--></sys></sys></time></stdio></iostream></span></span></span>
<br />
<br />
Here is the result of the above code.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG9TvqdAIQJU8HlToS0jbuOr2Xrlq5ZMKh3ROlROmoW-ASqd-nk187VX2He-wTsGLAiinfeYHcLpllgfkHbapzR29sDUnnz5DX31c7CrcUKyGWnecj5XydcPwBwIAZoYp4aWijLxNP81cM/s1600/clock.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG9TvqdAIQJU8HlToS0jbuOr2Xrlq5ZMKh3ROlROmoW-ASqd-nk187VX2He-wTsGLAiinfeYHcLpllgfkHbapzR29sDUnnz5DX31c7CrcUKyGWnecj5XydcPwBwIAZoYp4aWijLxNP81cM/s1600/clock.jpeg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">OpenCV Analog Clock</td></tr>
</tbody></table>
<br />
Hope these post helpful......<br />
<br />
Thanks........<br />
<br /></div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-2586906517427561969.post-55696955818587117672012-11-30T23:54:00.003-08:002013-01-07T05:00:09.641-08:00OpenCV Saving Image From Video<span style="font-family: Times New Roman;"><code><span style="font-size: medium;">This example save snapshot form the loaded video with a name of current time. Note that this code uses struct tm and time_t for accessing system time. And the code is written for Linux platform. Below is the code.</span></code></span><br />
<pre class="brush:cpp">#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <stdio.h>>
int main(int argc, char *argv[])
{
int i=0;
char image[1000];
cvNamedWindow("mainWin");
CvCapture* capture = cvCreateFileCapture( argv[1]);
if(argv[1]==NULL){
printf("Cannot laod video\n");
return 0;
}
IplImage* frame,*output;
struct tm *local;
time_t t;
printf("Press 's' to save image 'Esc' to exit\n");
while (1)
{
frame = cvQueryFrame( capture );
if ( !frame ) break;
cvShowImage( "mainWin", frame );
char c = cvWaitKey(33);
if (c=='s')
{
t = time(NULL);
local = localtime(&t);
output=cvCreateImage(cvGetSize(frame),8,3);
sprintf(image,"%s.jpg",asctime(local));
cvSaveImage(image,frame);
cvCopy(frame,output);
cvNamedWindow("Result");
cvShowImage("Result",output);
cvReleaseImage(&output);
i++;
}
if ( c == 27 ) break;
}
cvReleaseCapture( &capture );
cvDestroyWindow( "mainWin" );
return 0;
} </pre>
Hope these helpful.... </pre>
Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-2586906517427561969.post-76711708100269412862012-11-28T05:22:00.004-08:002013-06-19T03:45:28.792-07:00OpenCV Find Biggest Contour<div dir="ltr" style="text-align: left;" trbidi="on">
Here is an example to find largest contour from the input image. A contour can be considered as a sequence of points that define a specific object in an image. Here I took contours as the brightest object in the image. Contours can be easily extracted by thresholding the gray scale image. <br />
<br />
After creating the contour images the function to find biggest contour is called where contour scanner used to scan through each contour and find biggest contour.<br />
<br />
If you want C++ code, see my new post , <a href="http://harismoonamkunnu.blogspot.in/2013/06/opencv-find-biggest-contour-using-c.html" target="_blank"><b>OpenCV Find Biggest Contour Using C++</b></a><br />
<br />
Here is the C code<br />
<br />
<span style="color: #38761d;"></span><br />
<pre nbsp="nbsp" style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguBqXMEWbwmX-wGIFopE-K7cjYuKdaztYM70Kw80wjFxIClitiJzjc-nSxSNowVuDdKcSbmeJH89Dp5Vs4skeygOl8thWxQuOiIccSnfcMAQmbFDRArkjT2IKg_lGGjYqyenxUSPEbECc6/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 14px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><span style="color: #38761d;"><code style="color: darkgreen; word-wrap: normal;"> <pre class="brush:cpp">#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv/cv.h"
using namespace cv;
using namespace std;
cv::Mat FC_FindBiggestContours(cv::Mat src);
CvRect R;
int main()
{
cv::Mat src;
cv::Mat src_binary;
src=cv::imread("src.jpeg");
if(src.empty()){
cout<<"Cannot load the image !"<<endl;
return 0;
}
cvtColor(src, src_binary, CV_BGR2GRAY); // Convert BGR to gray
cv::threshold(src_binary, src_binary, 200, 255, 0); // Threshold the image to convert binary image
imshow("src_binary",src_binary);
src_binary=FC_FindBiggestContours(src_binary);
rectangle(src, Point(R.x,R.y), Point(R.x+R.width,R.y+R.height), Scalar(0,255,0),2,8, 0);
imshow("Largest Contour", src_binary);
imshow("Source",src);
cvWaitKey(0); // Wait for key press
return 0;
}
cv::Mat FC_FindBiggestContours(cv::Mat mat_src)
{
IplImage temp=mat_src;
IplImage *src_img=cvCreateImage(cvSize(temp.width,temp.height),IPL_DEPTH_32S,1);
IplImage *dest=cvCreateImage(cvSize(temp.width,temp.height),IPL_DEPTH_8U,1);
CvArr* _mask=&temp;
int poly1Hull0=1;
CvPoint offset;
offset.x=0;
offset.y=0;
CvMat mstub, *mask = cvGetMat( _mask, &mstub );
CvMemStorage* tempStorage = cvCreateMemStorage();
CvSeq *contours, *c;
int nContours = 0;
double largest_length = 0,len = 0;
CvContourScanner scanner;
// clean up raw mask
cvMorphologyEx( mask, mask, 0, 0, CV_MOP_OPEN, 1 );
cvMorphologyEx( mask, mask, 0, 0, CV_MOP_CLOSE, 1 );
// find contours around only bigger regions
scanner = cvStartFindContours( mask, tempStorage,
sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset );
while( (c = cvFindNextContour( scanner )) != 0 )
{
len = cvContourPerimeter( c );
if(len > largest_length)
{
largest_length = len;
}
}
contours=cvEndFindContours( &scanner );
scanner = cvStartFindContours( mask, tempStorage,
sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset );
while( (c = cvFindNextContour( scanner )) != 0 )
{
len = cvContourPerimeter( c );
double q = largest_length ;
if( len < q ) //Get rid of blob if it's perimeter is too small
cvSubstituteContour( scanner, 0 );
else //Smooth it's edges if it's large enough
{
CvSeq* newC;
if( poly1Hull0 ) //Polygonal approximation of the segmentation
newC = cvApproxPoly( c, sizeof(CvContour), tempStorage, CV_POLY_APPROX_DP, 2, 0 );
else //Convex Hull of the segmentation
newC = cvConvexHull2( c, tempStorage, CV_CLOCKWISE, 1 );
cvSubstituteContour( scanner, newC );
nContours++;
R=cvBoundingRect(c,0);
}
}
contours = cvEndFindContours( &scanner );
// paint the found regions back into the image
cvZero( src_img );
cvZero( _mask );
for( c=contours; c != 0; c = c->h_next )
{
cvDrawContours( src_img, c, cvScalarAll(1), cvScalarAll(1), -1, -1, 8,
cvPoint(-offset.x,-offset.y));
}
cvReleaseMemStorage( &tempStorage );
// convert to 8 bit IplImage
for( int i = 0; i < src_img->height; i++ )
for( int j = 0; j < src_img->width; j++ )
{
int idx = CV_IMAGE_ELEM( src_img, int, i, j ); //get reference to pixel at (col,row),
uchar* dst = &CV_IMAGE_ELEM( dest, uchar, i, j ); //for multi-channel images (col) should be multiplied by number of channels */
if( idx == -1 || idx == 1 )
*dst = (uchar)255;
else if( idx <= 0 || idx > 1 )
*dst = (uchar)0; // should not get here
else {
*dst = (uchar)0;
}
}
cvReleaseImage(&src_img);
Mat ret=cvarrToMat(dest);
return ret;
} </pre>
</code></span></pre>
<span style="color: #38761d;">
</span>
The source image:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFXMbylz0JB61gMGI2QAzJffVwG2CrYbmSqaHBJLIoDFc8boUIjA39gJV-8wpRhzyDLxeTmMa6ZBy17rdgSu8jhZwm9qpBCrQVOoHV3MlrYQ6nz1zA5Lt6P2Rqrg0XUtqSlr5UNmJwNtik/s1600/src.jpeg" height="213" style="margin-left: auto; margin-right: auto;" title="" width="320" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">src.jpeg</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Result:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbPp1y-tGq6RwIOgkm2rrRSad9ZMGP8t4ATlyiBcU9fp3xp0uJhOy6eQOF61xZ0C9iZglDscheSH6TSzYBvj4eL6Zvu927s-5npMFW9RDiuI3Da1hVN4LCVpLIeU080YD-U_A6ts1H5epr/s1600/result.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbPp1y-tGq6RwIOgkm2rrRSad9ZMGP8t4ATlyiBcU9fp3xp0uJhOy6eQOF61xZ0C9iZglDscheSH6TSzYBvj4eL6Zvu927s-5npMFW9RDiuI3Da1hVN4LCVpLIeU080YD-U_A6ts1H5epr/s1600/result.png" height="230" width="320" /></a></div>
Hope these help. <br />
</div>
Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-2586906517427561969.post-27230848623626659602012-11-26T04:37:00.001-08:002012-12-26T02:23:22.832-08:00Load Modify and Save Image Using OpenCV HighguiThis is simple example for load image, do some image manipulation and save the result.<pre class="brush:cpp"><br /><br />#include <iostream><br />#include "opencv2/highgui/highgui.hpp"<br />#include "opencv/cv.h"<br /><br />using namespace std;<br /><br />int main()<br />{<br /> cv::Mat src;<br /> cv::Mat src_binary;<br /><br /> src=cv::imread("source.jpeg");<br /> if(src.empty()){<br /> cout<<"Cannot load the image !"<<endl;<br /> return 0;<br /> }<br /><br /> imshow("src",src);<br /><br /> cvtColor(src, src_binary, CV_BGR2GRAY); // Convert BGR to gray<br /> cv::threshold(src_binary, src_binary, 100, 255, 0); // Threshold the image to convert binary image<br /><br /> imshow("src_binary",src_binary);<br /> imwrite("/sdcard/result.jpeg",src_binary); // save image<br /><br /> cvWaitKey(0); // Wait for key press<br /> return 0;<br />}<br /><br /><br /></pre>Unknownnoreply@blogger.com0