Sample files for image scanning, basic Mat, file I/O. Added Victors removed tutorials back in the system. Some typo fixing.Expanded conf.py with new global links.
parent
3d9cb082c9
commit
ffe7a658fb
21 changed files with 1373 additions and 11 deletions
@ -0,0 +1,62 @@ |
||||
.. _CameraCalibrationSquareChessBoardTutorial: |
||||
|
||||
Camera calibration with square chessboard |
||||
***************************************** |
||||
|
||||
.. highlight:: cpp |
||||
|
||||
The goal of this tutorial is to learn how to calibrate a camera given a set of chessboard images. |
||||
|
||||
*Test data*: use images in your data/chess folder. |
||||
|
||||
#. |
||||
Compile opencv with samples by setting ``BUILD_EXAMPLES`` to ``ON`` in cmake configuration. |
||||
|
||||
#. |
||||
Go to ``bin`` folder and use ``imagelist_creator`` to create an ``XML/YAML`` list of your images. |
||||
|
||||
#. |
||||
Then, run ``calibration`` sample to get camera parameters. Use square size equal to 3cm. |
||||
|
||||
Pose estimation |
||||
=============== |
||||
|
||||
Now, let us write a code that detects a chessboard in a new image and finds its distance from the camera. You can apply the same method to any object with known 3D geometry that you can detect in an image. |
||||
|
||||
*Test data*: use chess_test*.jpg images from your data folder. |
||||
|
||||
#. |
||||
Create an empty console project. Load a test image: :: |
||||
|
||||
Mat img = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); |
||||
|
||||
#. |
||||
Detect a chessboard in this image using findChessboard function. :: |
||||
|
||||
bool found = findChessboardCorners( img, boardSize, ptvec, CV_CALIB_CB_ADAPTIVE_THRESH ); |
||||
|
||||
#. |
||||
Now, write a function that generates a ``vector<Point3f>`` array of 3d coordinates of a chessboard in any coordinate system. For simplicity, let us choose a system such that one of the chessboard corners is in the origin and the board is in the plane *z = 0*. |
||||
|
||||
#. |
||||
Read camera parameters from XML/YAML file: :: |
||||
|
||||
FileStorage fs(filename, FileStorage::READ); |
||||
Mat intrinsics, distortion; |
||||
fs["camera_matrix"] >> intrinsics; |
||||
fs["distortion_coefficients"] >> distortion; |
||||
|
||||
#. |
||||
Now we are ready to find chessboard pose by running ``solvePnP``: :: |
||||
|
||||
vector<Point3f> boardPoints; |
||||
// fill the array |
||||
... |
||||
|
||||
solvePnP(Mat(boardPoints), Mat(foundBoardCorners), cameraMatrix, |
||||
distCoeffs, rvec, tvec, false); |
||||
|
||||
#. |
||||
Calculate reprojection error like it is done in ``calibration`` sample (see ``opencv/samples/cpp/calibration.cpp``, function ``computeReprojectionErrors``). |
||||
|
||||
Question: how to calculate the distance from the camera origin to any of the corners? |
After Width: | Height: | Size: 6.6 KiB |
@ -0,0 +1,15 @@ |
||||
.. _discretFourierTransform: |
||||
|
||||
Discrete Fourier Transform |
||||
************************** |
||||
|
||||
Goal |
||||
==== |
||||
|
||||
We'll seek answers for the following questions: |
||||
|
||||
.. container:: enumeratevisibleitemswithsquare |
||||
|
||||
+ What is a Fourier transform and why use it? |
||||
+ How to do it in OpenCV? |
||||
+ Usage of functions such as: :imgprocfilter:`copyMakeBorder() <copymakeborder>`, :operationsonarrays:`merge() <merge>`, :operationsonarrays:`dft() <dft>`, :operationsonarrays:`getOptimalDFTSize() <getoptimaldftsize>`, :operationsonarrays:`log() <log>` and :operationsonarrays:`normalize() <normalize>` . |
After Width: | Height: | Size: 6.2 KiB |
@ -1,7 +1,7 @@ |
||||
.. |Author_AnaH| unicode:: Ana U+0020 Huam U+00E1 n |
||||
.. |Author_BernatG| unicode:: Bern U+00E1 t U+0020 G U+00E1 bor |
||||
.. |Author_AndreyK| unicode:: Andrey U+0020 Kamaev |
||||
|
||||
.. |Author_VictorE| unicode:: Victor Eruhimov |
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,72 @@ |
||||
.. _detectionOfPlanarObjects: |
||||
|
||||
Detection of planar objects |
||||
*************************** |
||||
|
||||
.. highlight:: cpp |
||||
|
||||
The goal of this tutorial is to learn how to use *features2d* and *calib3d* modules for detecting known planar objects in scenes. |
||||
|
||||
*Test data*: use images in your data folder, for instance, ``box.png`` and ``box_in_scene.png``. |
||||
|
||||
#. |
||||
Create a new console project. Read two input images. :: |
||||
|
||||
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); |
||||
Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE); |
||||
|
||||
#. |
||||
Detect keypoints in both images. :: |
||||
|
||||
// detecting keypoints |
||||
FastFeatureDetector detector(15); |
||||
vector<KeyPoint> keypoints1; |
||||
detector.detect(img1, keypoints1); |
||||
|
||||
... // do the same for the second image |
||||
|
||||
#. |
||||
Compute descriptors for each of the keypoints. :: |
||||
|
||||
// computing descriptors |
||||
SurfDescriptorExtractor extractor; |
||||
Mat descriptors1; |
||||
extractor.compute(img1, keypoints1, descriptors1); |
||||
|
||||
... // process keypoints from the second image as well |
||||
|
||||
#. |
||||
Now, find the closest matches between descriptors from the first image to the second: :: |
||||
|
||||
// matching descriptors |
||||
BruteForceMatcher<L2<float> > matcher; |
||||
vector<DMatch> matches; |
||||
matcher.match(descriptors1, descriptors2, matches); |
||||
|
||||
#. |
||||
Visualize the results: :: |
||||
|
||||
// drawing the results |
||||
namedWindow("matches", 1); |
||||
Mat img_matches; |
||||
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches); |
||||
imshow("matches", img_matches); |
||||
waitKey(0); |
||||
|
||||
#. |
||||
Find the homography transformation between two sets of points: :: |
||||
|
||||
vector<Point2f> points1, points2; |
||||
// fill the arrays with the points |
||||
.... |
||||
Mat H = findHomography(Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold); |
||||
|
||||
|
||||
#. |
||||
Create a set of inlier matches and draw them. Use perspectiveTransform function to map points with homography: |
||||
|
||||
Mat points1Projected; |
||||
perspectiveTransform(Mat(points1), points1Projected, H); |
||||
|
||||
#. |
||||
Use ``drawMatches`` for drawing inliers. |
After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1,172 @@ |
||||
/**
|
||||
* @file Drawing_1.cpp |
||||
* @brief Simple sample code |
||||
*/ |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
#include <opencv2/highgui/highgui.hpp> |
||||
|
||||
#define w 400 |
||||
|
||||
using namespace cv; |
||||
|
||||
/// Function headers
|
||||
void MyEllipse( Mat img, double angle ); |
||||
void MyFilledCircle( Mat img, Point center ); |
||||
void MyPolygon( Mat img ); |
||||
void MyLine( Mat img, Point start, Point end ); |
||||
|
||||
/**
|
||||
* @function main |
||||
* @brief Main function |
||||
*/ |
||||
int main( int argc, char **argv ){ |
||||
|
||||
/// Windows names
|
||||
char atom_window[] = "Drawing 1: Atom"; |
||||
char rook_window[] = "Drawing 2: Rook"; |
||||
|
||||
/// Create black empty images
|
||||
Mat atom_image = Mat::zeros( w, w, CV_8UC3 ); |
||||
Mat rook_image = Mat::zeros( w, w, CV_8UC3 ); |
||||
|
||||
/// 1. Draw a simple atom:
|
||||
/// -----------------------
|
||||
|
||||
/// 1.a. Creating ellipses
|
||||
MyEllipse( atom_image, 90 ); |
||||
MyEllipse( atom_image, 0 ); |
||||
MyEllipse( atom_image, 45 ); |
||||
MyEllipse( atom_image, -45 ); |
||||
|
||||
/// 1.b. Creating circles
|
||||
MyFilledCircle( atom_image, Point( w/2.0, w/2.0) ); |
||||
|
||||
/// 2. Draw a rook
|
||||
/// ------------------
|
||||
|
||||
/// 2.a. Create a convex polygon
|
||||
MyPolygon( rook_image ); |
||||
|
||||
/// 2.b. Creating rectangles
|
||||
rectangle( rook_image, |
||||
Point( 0, 7*w/8.0 ), |
||||
Point( w, w), |
||||
Scalar( 0, 255, 255 ), |
||||
-1, |
||||
8 ); |
||||
|
||||
/// 2.c. Create a few lines
|
||||
MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) ); |
||||
MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) ); |
||||
MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) ); |
||||
MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) ); |
||||
|
||||
/// 3. Display your stuff!
|
||||
imshow( atom_window, atom_image ); |
||||
cvMoveWindow( atom_window, 0, 200 ); |
||||
imshow( rook_window, rook_image ); |
||||
cvMoveWindow( rook_window, w, 200 ); |
||||
|
||||
waitKey( 0 ); |
||||
return(0); |
||||
} |
||||
|
||||
/// Function Declaration
|
||||
|
||||
/**
|
||||
* @function MyEllipse |
||||
* @brief Draw a fixed-size ellipse with different angles |
||||
*/ |
||||
void MyEllipse( Mat img, double angle ) |
||||
{ |
||||
int thickness = 2; |
||||
int lineType = 8; |
||||
|
||||
ellipse( img, |
||||
Point( w/2.0, w/2.0 ), |
||||
Size( w/4.0, w/16.0 ), |
||||
angle, |
||||
0,
|
||||
360, |
||||
Scalar( 255, 0, 0 ), |
||||
thickness, |
||||
lineType );
|
||||
} |
||||
|
||||
/**
|
||||
* @function MyFilledCircle |
||||
* @brief Draw a fixed-size filled circle |
||||
*/ |
||||
void MyFilledCircle( Mat img, Point center ) |
||||
{ |
||||
int thickness = -1; |
||||
int lineType = 8; |
||||
|
||||
circle( img,
|
||||
center, |
||||
w/32.0, |
||||
Scalar( 0, 0, 255 ), |
||||
thickness,
|
||||
lineType ); |
||||
} |
||||
|
||||
/**
|
||||
* @function MyPolygon |
||||
* @function Draw a simple concave polygon (rook) |
||||
*/ |
||||
void MyPolygon( Mat img ) |
||||
{ |
||||
int lineType = 8; |
||||
|
||||
/** Create some points */ |
||||
Point rook_points[1][20]; |
||||
rook_points[0][0] = Point( w/4.0, 7*w/8.0 ); |
||||
rook_points[0][1] = Point( 3*w/4.0, 7*w/8.0 ); |
||||
rook_points[0][2] = Point( 3*w/4.0, 13*w/16.0 ); |
||||
rook_points[0][3] = Point( 11*w/16.0, 13*w/16.0 ); |
||||
rook_points[0][4] = Point( 19*w/32.0, 3*w/8.0 ); |
||||
rook_points[0][5] = Point( 3*w/4.0, 3*w/8.0 ); |
||||
rook_points[0][6] = Point( 3*w/4.0, w/8.0 ); |
||||
rook_points[0][7] = Point( 26*w/40.0, w/8.0 ); |
||||
rook_points[0][8] = Point( 26*w/40.0, w/4.0 ); |
||||
rook_points[0][9] = Point( 22*w/40.0, w/4.0 ); |
||||
rook_points[0][10] = Point( 22*w/40.0, w/8.0 ); |
||||
rook_points[0][11] = Point( 18*w/40.0, w/8.0 ); |
||||
rook_points[0][12] = Point( 18*w/40.0, w/4.0 ); |
||||
rook_points[0][13] = Point( 14*w/40.0, w/4.0 ); |
||||
rook_points[0][14] = Point( 14*w/40.0, w/8.0 ); |
||||
rook_points[0][15] = Point( w/4.0, w/8.0 ); |
||||
rook_points[0][16] = Point( w/4.0, 3*w/8.0 ); |
||||
rook_points[0][17] = Point( 13*w/32.0, 3*w/8.0 ); |
||||
rook_points[0][18] = Point( 5*w/16.0, 13*w/16.0 ); |
||||
rook_points[0][19] = Point( w/4.0, 13*w/16.0) ; |
||||
|
||||
const Point* ppt[1] = { rook_points[0] }; |
||||
int npt[] = { 20 }; |
||||
|
||||
fillPoly( img, |
||||
ppt, |
||||
npt, |
||||
1, |
||||
Scalar( 255, 255, 255 ), |
||||
lineType );
|
||||
} |
||||
|
||||
/**
|
||||
* @function MyLine |
||||
* @brief Draw a simple line |
||||
*/ |
||||
void MyLine( Mat img, Point start, Point end ) |
||||
{ |
||||
int thickness = 2; |
||||
int lineType = 8; |
||||
line( img,
|
||||
start, |
||||
end, |
||||
Scalar( 0, 0, 0 ), |
||||
thickness, |
||||
lineType ); |
||||
} |
||||
|
||||
|
@ -0,0 +1,326 @@ |
||||
/**
|
||||
* @file Drawing_2.cpp |
||||
* @brief Simple sample code |
||||
*/ |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
#include <opencv2/highgui/highgui.hpp> |
||||
#include <iostream> |
||||
#include <stdio.h> |
||||
|
||||
using namespace cv; |
||||
|
||||
/// Global Variables
|
||||
const int NUMBER = 100;
|
||||
const int DELAY = 5; |
||||
|
||||
const int window_width = 900; |
||||
const int window_height = 600; |
||||
int x_1 = -window_width/2; |
||||
int x_2 = window_width*3/2; |
||||
int y_1 = -window_width/2; |
||||
int y_2 = window_width*3/2; |
||||
|
||||
/// Function headers
|
||||
static Scalar randomColor( RNG& rng ); |
||||
int Drawing_Random_Lines( Mat image, char* window_name, RNG rng ); |
||||
int Drawing_Random_Rectangles( Mat image, char* window_name, RNG rng ); |
||||
int Drawing_Random_Ellipses( Mat image, char* window_name, RNG rng ); |
||||
int Drawing_Random_Polylines( Mat image, char* window_name, RNG rng ); |
||||
int Drawing_Random_Filled_Polygons( Mat image, char* window_name, RNG rng ); |
||||
int Drawing_Random_Circles( Mat image, char* window_name, RNG rng ); |
||||
int Displaying_Random_Text( Mat image, char* window_name, RNG rng ); |
||||
int Displaying_Big_End( Mat image, char* window_name, RNG rng ); |
||||
|
||||
|
||||
/**
|
||||
* @function main |
||||
*/ |
||||
int main( int argc, char** argv ) |
||||
{ |
||||
int c; |
||||
|
||||
/// Start creating a window
|
||||
char window_name[] = "Drawing_2 Tutorial"; |
||||
|
||||
/// Also create a random object (RNG)
|
||||
RNG rng( 0xFFFFFFFF );
|
||||
|
||||
/// Initialize a matrix filled with zeros
|
||||
Mat image = Mat::zeros( window_height, window_width, CV_8UC3 ); |
||||
/// Show it in a window during DELAY ms
|
||||
imshow( window_name, image );
|
||||
waitKey( DELAY ); |
||||
|
||||
/// Now, let's draw some lines
|
||||
c = Drawing_Random_Lines(image, window_name, rng); |
||||
if( c != 0 ) return 0; |
||||
|
||||
/// Go on drawing, this time nice rectangles
|
||||
c = Drawing_Random_Rectangles(image, window_name, rng); |
||||
if( c != 0 ) return 0; |
||||
|
||||
/// Draw some ellipses
|
||||
c = Drawing_Random_Ellipses( image, window_name, rng ); |
||||
if( c != 0 ) return 0; |
||||
|
||||
/// Now some polylines
|
||||
c = Drawing_Random_Polylines( image, window_name, rng ); |
||||
if( c != 0 ) return 0; |
||||
|
||||
/// Draw filled polygons
|
||||
c = Drawing_Random_Filled_Polygons( image, window_name, rng ); |
||||
if( c != 0 ) return 0; |
||||
|
||||
/// Draw circles
|
||||
c = Drawing_Random_Circles( image, window_name, rng ); |
||||
if( c != 0 ) return 0; |
||||
|
||||
/// Display text in random positions
|
||||
c = Displaying_Random_Text( image, window_name, rng ); |
||||
if( c != 0 ) return 0; |
||||
|
||||
/// Displaying the big end!
|
||||
c = Displaying_Big_End( image, window_name, rng ); |
||||
if( c != 0 ) return 0; |
||||
|
||||
waitKey(0); |
||||
return 0; |
||||
} |
||||
|
||||
/// Function definitions
|
||||
|
||||
/**
|
||||
* @function randomColor |
||||
* @brief Produces a random color given a random object |
||||
*/ |
||||
static Scalar randomColor( RNG& rng ) |
||||
{ |
||||
int icolor = (unsigned) rng; |
||||
return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 ); |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* @function Drawing_Random_Lines |
||||
*/ |
||||
int Drawing_Random_Lines( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
int lineType = 8; |
||||
Point pt1, pt2; |
||||
|
||||
for( int i = 0; i < NUMBER; i++ ) |
||||
{ |
||||
pt1.x = rng.uniform( x_1, x_2 ); |
||||
pt1.y = rng.uniform( y_1, y_2 ); |
||||
pt2.x = rng.uniform( x_1, x_2 ); |
||||
pt2.y = rng.uniform( y_1, y_2 ); |
||||
|
||||
line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 ); |
||||
imshow( window_name, image ); |
||||
if( waitKey( DELAY ) >= 0 ) |
||||
{ return -1; } |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* @function Drawing_Rectangles |
||||
*/ |
||||
int Drawing_Random_Rectangles( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
Point pt1, pt2; |
||||
int lineType = 8; |
||||
int thickness = rng.uniform( -3, 10 ); |
||||
|
||||
for( int i = 0; i < NUMBER; i++ ) |
||||
{ |
||||
pt1.x = rng.uniform( x_1, x_2 ); |
||||
pt1.y = rng.uniform( y_1, y_2 ); |
||||
pt2.x = rng.uniform( x_1, x_2 ); |
||||
pt2.y = rng.uniform( y_1, y_2 ); |
||||
|
||||
rectangle( image, pt1, pt2, randomColor(rng), MAX( thickness, -1 ), lineType ); |
||||
|
||||
imshow( window_name, image ); |
||||
if( waitKey( DELAY ) >= 0 ) |
||||
{ return -1; }
|
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* @function Drawing_Random_Ellipses |
||||
*/ |
||||
int Drawing_Random_Ellipses( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
int lineType = 8; |
||||
|
||||
for ( int i = 0; i < NUMBER; i++ ) |
||||
{ |
||||
Point center; |
||||
center.x = rng.uniform(x_1, x_2); |
||||
center.y = rng.uniform(y_1, y_2); |
||||
|
||||
Size axes; |
||||
axes.width = rng.uniform(0, 200); |
||||
axes.height = rng.uniform(0, 200); |
||||
|
||||
double angle = rng.uniform(0, 180); |
||||
|
||||
ellipse( image, center, axes, angle, angle - 100, angle + 200, |
||||
randomColor(rng), rng.uniform(-1,9), lineType ); |
||||
|
||||
imshow( window_name, image ); |
||||
|
||||
if( waitKey(DELAY) >= 0 )
|
||||
{ return -1; } |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* @function Drawing_Random_Polylines |
||||
*/ |
||||
int Drawing_Random_Polylines( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
int lineType = 8; |
||||
|
||||
for( int i = 0; i< NUMBER; i++ ) |
||||
{ |
||||
Point pt[2][3]; |
||||
pt[0][0].x = rng.uniform(x_1, x_2); |
||||
pt[0][0].y = rng.uniform(y_1, y_2); |
||||
pt[0][1].x = rng.uniform(x_1, x_2);
|
||||
pt[0][1].y = rng.uniform(y_1, y_2);
|
||||
pt[0][2].x = rng.uniform(x_1, x_2); |
||||
pt[0][2].y = rng.uniform(y_1, y_2); |
||||
pt[1][0].x = rng.uniform(x_1, x_2);
|
||||
pt[1][0].y = rng.uniform(y_1, y_2); |
||||
pt[1][1].x = rng.uniform(x_1, x_2);
|
||||
pt[1][1].y = rng.uniform(y_1, y_2); |
||||
pt[1][2].x = rng.uniform(x_1, x_2);
|
||||
pt[1][2].y = rng.uniform(y_1, y_2); |
||||
|
||||
const Point* ppt[2] = {pt[0], pt[1]}; |
||||
int npt[] = {3, 3}; |
||||
|
||||
polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1,10), lineType); |
||||
|
||||
imshow( window_name, image ); |
||||
if( waitKey(DELAY) >= 0 ) |
||||
{ return -1; } |
||||
} |
||||
return 0; |
||||
}
|
||||
|
||||
/**
|
||||
* @function Drawing_Random_Filled_Polygons |
||||
*/ |
||||
int Drawing_Random_Filled_Polygons( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
int lineType = 8; |
||||
|
||||
for ( int i = 0; i < NUMBER; i++ ) |
||||
{ |
||||
Point pt[2][3]; |
||||
pt[0][0].x = rng.uniform(x_1, x_2); |
||||
pt[0][0].y = rng.uniform(y_1, y_2); |
||||
pt[0][1].x = rng.uniform(x_1, x_2);
|
||||
pt[0][1].y = rng.uniform(y_1, y_2);
|
||||
pt[0][2].x = rng.uniform(x_1, x_2); |
||||
pt[0][2].y = rng.uniform(y_1, y_2); |
||||
pt[1][0].x = rng.uniform(x_1, x_2);
|
||||
pt[1][0].y = rng.uniform(y_1, y_2); |
||||
pt[1][1].x = rng.uniform(x_1, x_2);
|
||||
pt[1][1].y = rng.uniform(y_1, y_2); |
||||
pt[1][2].x = rng.uniform(x_1, x_2);
|
||||
pt[1][2].y = rng.uniform(y_1, y_2); |
||||
|
||||
const Point* ppt[2] = {pt[0], pt[1]}; |
||||
int npt[] = {3, 3}; |
||||
|
||||
fillPoly( image, ppt, npt, 2, randomColor(rng), lineType ); |
||||
|
||||
imshow( window_name, image ); |
||||
if( waitKey(DELAY) >= 0 ) |
||||
{ return -1; } |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* @function Drawing_Random_Circles |
||||
*/ |
||||
int Drawing_Random_Circles( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
int lineType = 8; |
||||
|
||||
for (int i = 0; i < NUMBER; i++) |
||||
{ |
||||
Point center; |
||||
center.x = rng.uniform(x_1, x_2); |
||||
center.y = rng.uniform(y_1, y_2); |
||||
|
||||
circle( image, center, rng.uniform(0, 300), randomColor(rng), |
||||
rng.uniform(-1, 9), lineType ); |
||||
|
||||
imshow( window_name, image ); |
||||
if( waitKey(DELAY) >= 0 ) |
||||
{ return -1; } |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* @function Displaying_Random_Text |
||||
*/ |
||||
int Displaying_Random_Text( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
int lineType = 8; |
||||
|
||||
for ( int i = 1; i < NUMBER; i++ ) |
||||
{ |
||||
Point org; |
||||
org.x = rng.uniform(x_1, x_2); |
||||
org.y = rng.uniform(y_1, y_2); |
||||
|
||||
putText( image, "Testing text rendering", org, rng.uniform(0,8), |
||||
rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType); |
||||
|
||||
imshow( window_name, image ); |
||||
if( waitKey(DELAY) >= 0 ) |
||||
{ return -1; } |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* @function Displaying_Big_End |
||||
*/ |
||||
int Displaying_Big_End( Mat image, char* window_name, RNG rng ) |
||||
{ |
||||
Size textsize = getTextSize("OpenCV forever!", CV_FONT_HERSHEY_COMPLEX, 3, 5, 0); |
||||
Point org((window_width - textsize.width)/2, (window_height - textsize.height)/2); |
||||
int lineType = 8; |
||||
|
||||
Mat image2; |
||||
|
||||
for( int i = 0; i < 255; i += 2 ) |
||||
{ |
||||
image2 = image - Scalar::all(i); |
||||
putText( image2, "OpenCV forever!", org, CV_FONT_HERSHEY_COMPLEX, 3, |
||||
Scalar(i, i, 255), 5, lineType ); |
||||
|
||||
imshow( window_name, image2 ); |
||||
if( waitKey(DELAY) >= 0 ) |
||||
{ return -1; } |
||||
} |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,79 @@ |
||||
#include "opencv2/core/core.hpp" |
||||
#include "opencv2/imgproc/imgproc.hpp" |
||||
#include "opencv2/highgui/highgui.hpp" |
||||
|
||||
#include <iostream> |
||||
|
||||
using namespace cv; |
||||
using namespace std; |
||||
|
||||
void help(char* progName) |
||||
{ |
||||
cout << endl
|
||||
<< "This program demonstrated the use of the discrete Fourier transform (DFT). " << endl |
||||
<< "The dft of an image is taken and it's power spectrum is displayed." << endl |
||||
<< "Usage:" << endl |
||||
<< progName << " [image_name -- default lena.jpg] " << endl << endl; |
||||
} |
||||
|
||||
int main(int argc, char ** argv) |
||||
{ |
||||
help(argv[0]); |
||||
|
||||
const char* filename = argc >=2 ? argv[1] : "lena.jpg"; |
||||
|
||||
Mat I = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); |
||||
if( I.empty()) |
||||
return -1; |
||||
|
||||
Mat padded; //expand input image to optimal size
|
||||
int m = getOptimalDFTSize( I.rows ); |
||||
int n = getOptimalDFTSize( I.cols ); // on the border keep the values
|
||||
copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0)); |
||||
|
||||
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)}; |
||||
Mat complexI; |
||||
merge(planes, 2, complexI); // Add to the expanded another plane with zeros
|
||||
|
||||
dft(complexI, complexI); // this way the result may fit in the source matrix
|
||||
|
||||
// compute the magnitude and switch to logarithmic scale
|
||||
// => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
|
||||
split(complexI, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
|
||||
magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
|
||||
Mat magI = planes[0]; |
||||
|
||||
magI += Scalar::all(1); // switch to logarithmic scale
|
||||
log(magI, magI); |
||||
|
||||
// crop the spectrum, if it has an odd number of rows or columns
|
||||
magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2)); |
||||
|
||||
// rearrange the quadrants of Fourier image so that the origin is at the image center
|
||||
int cx = magI.cols/2; |
||||
int cy = magI.rows/2; |
||||
|
||||
Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
|
||||
Mat q1(magI, Rect(cx, 0, cx, cy)); // Top-Right
|
||||
Mat q2(magI, Rect(0, cy, cx, cy)); // Bottom-Left
|
||||
Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right
|
||||
|
||||
Mat tmp; // swap quadrants (Top-Left with Bottom-Right)
|
||||
q0.copyTo(tmp); |
||||
q3.copyTo(q0); |
||||
tmp.copyTo(q3); |
||||
|
||||
q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
|
||||
q2.copyTo(q1); |
||||
tmp.copyTo(q2); |
||||
|
||||
normalize(magI, magI, 0, 1, CV_MINMAX); // Transform the matrix with float values into a
|
||||
// viewable image form (float between values 0 and 1).
|
||||
|
||||
imshow("Input Image" , I ); // Show the result
|
||||
imshow("spectrum magnitude", magI);
|
||||
waitKey(); |
||||
|
||||
return 0; |
||||
} |
||||
|
@ -0,0 +1,144 @@ |
||||
#include "opencv2/core/core.hpp" |
||||
#include <iostream> |
||||
#include <string> |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
|
||||
void help(char** av) |
||||
{ |
||||
cout << endl
|
||||
<< av[0] << " shows the usage of the OpenCV serialization functionality." << endl |
||||
<< "usage: " << endl |
||||
<< av[0] << " outputfile.yml.gz" << endl |
||||
<< "The output file may be either XML (xml) or YAML (yml/yaml). You can even compress it by " |
||||
<< "specifying this in its extension like xml.gz yaml.gz etc... " << endl |
||||
<< "With FileStorage you can serialize objects in OpenCV by using the << and >> operators" << endl |
||||
<< "For example: - create a class and have it serialized" << endl |
||||
<< " - use it to read and write matrices." << endl; |
||||
} |
||||
|
||||
class MyData |
||||
{ |
||||
public: |
||||
MyData() : A(0), X(0), id() |
||||
{} |
||||
explicit MyData(int) : A(97), X(CV_PI), id("mydata1234") // explicit to avoid implicit conversion
|
||||
{} |
||||
|
||||
void write(FileStorage& fs) const //Write serialization for this class
|
||||
{ |
||||
fs << "{" << "A" << A << "X" << X << "id" << id << "}"; |
||||
} |
||||
void read(const FileNode& node) //Read serialization for this class
|
||||
{ |
||||
A = (int)node["A"]; |
||||
X = (double)node["X"]; |
||||
id = (string)node["id"]; |
||||
} |
||||
public: // Data Members
|
||||
int A; |
||||
double X; |
||||
string id; |
||||
}; |
||||
|
||||
//These write and read functions must be defined for the serialization in FileStorage to work
|
||||
void write(FileStorage& fs, const std::string&, const MyData& x) |
||||
{ |
||||
x.write(fs); |
||||
} |
||||
void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()){ |
||||
if(node.empty()) |
||||
x = default_value; |
||||
else |
||||
x.read(node); |
||||
} |
||||
|
||||
// This function will print our custom class to the console
|
||||
ostream& operator<<(ostream& out, const MyData& m)
|
||||
{
|
||||
out << "{ id = " << m.id << ", "; |
||||
out << "X = " << m.X << ", "; |
||||
out << "A = " << m.A << "}"; |
||||
return out; |
||||
} |
||||
|
||||
int main(int ac, char** av) |
||||
{ |
||||
if (ac != 2) |
||||
{ |
||||
help(av); |
||||
return 1; |
||||
} |
||||
|
||||
string filename = av[1]; |
||||
|
||||
//write
|
||||
{ |
||||
Mat R = Mat_<double>::eye(3, 3), |
||||
T = Mat_<double>::zeros(3, 1); |
||||
|
||||
MyData m(1); |
||||
|
||||
FileStorage fs(filename, FileStorage::WRITE); |
||||
|
||||
|
||||
fs << "strings" << "["; |
||||
fs << "image1.jpg" << "Awesomeness" << "baboon.jpg"; |
||||
fs << "]"; |
||||
|
||||
fs << "R" << R; |
||||
fs << "T" << T; |
||||
|
||||
fs << "MyData" << m; |
||||
|
||||
cout << "Write Done." << endl; |
||||
} |
||||
|
||||
//read
|
||||
{ |
||||
cout << endl << "Reading: " << endl; |
||||
FileStorage fs(filename, FileStorage::READ); |
||||
|
||||
if (!fs.isOpened()) |
||||
{ |
||||
cerr << "Failed to open " << filename << endl; |
||||
help(av); |
||||
return 1; |
||||
} |
||||
|
||||
FileNode n = fs["strings"]; |
||||
if (n.type() != FileNode::SEQ) |
||||
{ |
||||
cerr << "strings is not a sequence! FAIL" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
|
||||
FileNodeIterator it = n.begin(), it_end = n.end(); |
||||
for (; it != it_end; ++it) |
||||
cout << (string)*it << endl; |
||||
|
||||
MyData m; |
||||
Mat R, T; |
||||
|
||||
fs["R"] >> R; |
||||
fs["T"] >> T; |
||||
fs["MyData"] >> m; |
||||
|
||||
cout << endl
|
||||
<< "R = " << R << "\n"; |
||||
cout << "T = " << T << endl << endl; |
||||
cout << "MyData = " << endl << m << endl << endl; |
||||
|
||||
//Show default behavior for non existing nodes
|
||||
cout << "Attempt to read NonExisting (should initialize the data structure with its default).";
|
||||
fs["NonExisting"] >> m; |
||||
cout << endl << "NonExisting = " << endl << m << endl; |
||||
} |
||||
|
||||
cout << endl
|
||||
<< "Tip: Open up " << filename << " with a text editor to see the serialized data." << endl; |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,85 @@ |
||||
/* For description look into the help() function. */ |
||||
|
||||
#include "opencv2/core/core.hpp" |
||||
#include <iostream> |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
|
||||
void help() |
||||
{ |
||||
cout |
||||
<< "\n--------------------------------------------------------------------------" << endl |
||||
<< "This program shows how to create matrices(cv::Mat) in OpenCV and its serial" |
||||
<< " out capabilities" << endl |
||||
<< "That is, cv::Mat M(...); M.create and cout << M. " << endl |
||||
<< "Shows how output can be formated to OpenCV, python, numpy, csv and C styles." << endl |
||||
<< "Usage:" << endl |
||||
<< "./cvout_sample" << endl |
||||
<< "--------------------------------------------------------------------------" << endl
|
||||
<< endl; |
||||
} |
||||
|
||||
int main(int,char**) |
||||
{ |
||||
help();
|
||||
// create by using the constructor
|
||||
Mat M(2,2, CV_8UC3, Scalar(0,0,255));
|
||||
cout << "M = " << endl << " " << M << endl << endl;
|
||||
|
||||
// create by using the create function()
|
||||
M.create(4,4, CV_8UC(2)); |
||||
cout << "M = "<< endl << " " << M << endl << endl; |
||||
|
||||
// create multidimensional matrices
|
||||
int sz[3] = {2,2,2};
|
||||
Mat L(3,sz, CV_8UC(1), Scalar::all(0)); |
||||
// Cannot print via operator <<
|
||||
|
||||
// Create using MATLAB style eye, ones or zero matrix
|
||||
Mat E = Mat::eye(4, 4, CV_64F);
|
||||
cout << "E = " << endl << " " << E << endl << endl; |
||||
|
||||
Mat O = Mat::ones(2, 2, CV_32F);
|
||||
cout << "O = " << endl << " " << O << endl << endl; |
||||
|
||||
Mat Z = Mat::zeros(3,3, CV_8UC1); |
||||
cout << "Z = " << endl << " " << Z << endl << endl; |
||||
|
||||
// create a 3x3 double-precision identity matrix
|
||||
Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
|
||||
cout << "C = " << endl << " " << C << endl << endl; |
||||
|
||||
Mat RowClone = C.row(1).clone(); |
||||
cout << "RowClone = " << endl << " " << RowClone << endl << endl; |
||||
|
||||
// Fill a matrix with random values
|
||||
Mat R = Mat(3, 2, CV_8UC3); |
||||
randu(R, Scalar::all(0), Scalar::all(255)); |
||||
|
||||
// Demonstrate the output formating options
|
||||
cout << "R (default) = " << endl << R << endl << endl; |
||||
cout << "R (python) = " << endl << format(R,"python") << endl << endl; |
||||
cout << "R (numpy) = " << endl << format(R,"numpy" ) << endl << endl; |
||||
cout << "R (csv) = " << endl << format(R,"csv" ) << endl << endl; |
||||
cout << "R (c) = " << endl << format(R,"C" ) << endl << endl; |
||||
|
||||
Point2f P(5, 1); |
||||
cout << "Point (2D) = " << P << endl << endl; |
||||
|
||||
Point3f P3f(2, 6, 7); |
||||
cout << "Point (3D) = " << P3f << endl << endl; |
||||
|
||||
|
||||
vector<float> v; |
||||
v.push_back( (float)CV_PI); v.push_back(2); v.push_back(3.01f); |
||||
|
||||
cout << "Vector of floats via Mat = " << Mat(v) << endl << endl; |
||||
|
||||
vector<Point2f> vPoints(20); |
||||
for (size_t E = 0; E < vPoints.size(); ++E) |
||||
vPoints[E] = Point2f((float)(E * 5), (float)(E % 7)); |
||||
|
||||
cout << "A vector of 2D Points = " << vPoints << endl << endl; |
||||
return 0; |
||||
} |
@ -0,0 +1,134 @@ |
||||
#include <stdio.h> |
||||
#include <iostream> |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
#include <opencv2/imgproc/imgproc.hpp> |
||||
#include <opencv2/highgui/highgui.hpp> |
||||
|
||||
using namespace cv; // The new C++ interface API is inside this namespace. Import it. |
||||
using namespace std; |
||||
|
||||
void help( char* progName) |
||||
{ |
||||
cout << endl << progName |
||||
<< " shows how to use cv::Mat and IplImages together (converting back and forth)." << endl |
||||
<< "Also contains example for image read, spliting the planes, merging back and " << endl |
||||
<< " color conversion, plus iterating through pixels. " << endl |
||||
<< "Usage:" << endl |
||||
<< progName << " [image-name Default: lena.jpg]" << endl << endl; |
||||
} |
||||
|
||||
// comment out the define to use only the latest C++ API |
||||
#define DEMO_MIXED_API_USE |
||||
|
||||
int main( int argc, char** argv ) |
||||
{ |
||||
help(argv[0]); |
||||
const char* imagename = argc > 1 ? argv[1] : "lena.jpg"; |
||||
|
||||
#ifdef DEMO_MIXED_API_USE |
||||
Ptr<IplImage> IplI = cvLoadImage(imagename); // Ptr<T> is safe ref-counting pointer class |
||||
if(IplI.empty()) |
||||
{ |
||||
cerr << "Can not load image " << imagename << endl; |
||||
return -1; |
||||
} |
||||
Mat I(IplI); // Convert to the new style container. Only header created. Image not copied. |
||||
#else |
||||
Mat I = imread(imagename); // the newer cvLoadImage alternative, MATLAB-style function |
||||
if( I.empty() ) // same as if( !I.data ) |
||||
{ |
||||
cerr << "Can not load image " << imagename << endl; |
||||
return -1; |
||||
} |
||||
#endif |
||||
|
||||
// convert image to YUV color space. The output image will be created automatically. |
||||
Mat I_YUV; |
||||
cvtColor(I, I_YUV, CV_BGR2YCrCb); |
||||
|
||||
vector<Mat> planes; // Use the STL's vector structure to store multiple Mat objects |
||||
split(I_YUV, planes); // split the image into separate color planes (Y U V) |
||||
|
||||
#if 0 // change it to 0 if you want to see a blurred and noisy version of this processing |
||||
// Mat scanning |
||||
// Method 1. process Y plane using an iterator |
||||
MatIterator_<uchar> it = planes[0].begin<uchar>(), it_end = planes[0].end<uchar>(); |
||||
for(; it != it_end; ++it) |
||||
{ |
||||
double v = *it * 1.7 + rand()%21 - 10; |
||||
*it = saturate_cast<uchar>(v*v/255); |
||||
} |
||||
|
||||
for( int y = 0; y < I_YUV.rows; y++ ) |
||||
{ |
||||
// Method 2. process the first chroma plane using pre-stored row pointer. |
||||
uchar* Uptr = planes[1].ptr<uchar>(y); |
||||
for( int x = 0; x < I_YUV.cols; x++ ) |
||||
{ |
||||
Uptr[x] = saturate_cast<uchar>((Uptr[x]-128)/2 + 128); |
||||
|
||||
// Method 3. process the second chroma plane using individual element access |
||||
uchar& Vxy = planes[2].at<uchar>(y, x); |
||||
Vxy = saturate_cast<uchar>((Vxy-128)/2 + 128); |
||||
} |
||||
} |
||||
|
||||
#else |
||||
|
||||
Mat noisyI(I.size(), CV_8U); // Create a matrix of the specified size and type |
||||
|
||||
// Fills the matrix with normally distributed random values (around number with deviation off). |
||||
// There is also randu() for uniformly distributed random number generation |
||||
randn(noisyI, Scalar::all(128), Scalar::all(20)); |
||||
|
||||
// blur the noisyI a bit, kernel size is 3x3 and both sigma's are set to 0.5 |
||||
GaussianBlur(noisyI, noisyI, Size(3, 3), 0.5, 0.5); |
||||
|
||||
const double brightness_gain = 0; |
||||
const double contrast_gain = 1.7; |
||||
|
||||
#ifdef DEMO_MIXED_API_USE |
||||
// To pass the new matrices to the functions that only work with IplImage or CvMat do: |
||||
// step 1) Convert the headers (tip: data will not be copied). |
||||
// step 2) call the function (tip: to pass a pointer do not forget unary "&" to form pointers) |
||||
|
||||
IplImage cv_planes_0 = planes[0], cv_noise = noisyI; |
||||
cvAddWeighted(&cv_planes_0, contrast_gain, &cv_noise, 1, -128 + brightness_gain, &cv_planes_0); |
||||
#else |
||||
addWeighted(planes[0], contrast_gain, noisyI, 1, -128 + brightness_gain, planes[0]); |
||||
#endif |
||||
|
||||
const double color_scale = 0.5; |
||||
// Mat::convertTo() replaces cvConvertScale. |
||||
// One must explicitly specify the output matrix type (we keep it intact - planes[1].type()) |
||||
planes[1].convertTo(planes[1], planes[1].type(), color_scale, 128*(1-color_scale)); |
||||
|
||||
// alternative form of cv::convertScale if we know the datatype at compile time ("uchar" here). |
||||
// This expression will not create any temporary arrays ( so should be almost as fast as above) |
||||
planes[2] = Mat_<uchar>(planes[2]*color_scale + 128*(1-color_scale)); |
||||
|
||||
// Mat::mul replaces cvMul(). Again, no temporary arrays are created in case of simple expressions. |
||||
planes[0] = planes[0].mul(planes[0], 1./255); |
||||
#endif |
||||
|
||||
|
||||
merge(planes, I_YUV); // now merge the results back |
||||
cvtColor(I_YUV, I, CV_YCrCb2BGR); // and produce the output RGB image |
||||
|
||||
|
||||
namedWindow("image with grain", CV_WINDOW_AUTOSIZE); // use this to create images |
||||
|
||||
#ifdef DEMO_MIXED_API_USE |
||||
// this is to demonstrate that I and IplI really share the data - the result of the above |
||||
// processing is stored in I and thus in IplI too. |
||||
cvShowImage("image with grain", IplI); |
||||
#else |
||||
imshow("image with grain", I); // the new MATLAB style function show |
||||
#endif |
||||
waitKey(); |
||||
|
||||
// Tip: No memory freeing is required! |
||||
// All the memory will be automatically released by the Vector<>, Mat and Ptr<> destructor. |
||||
return 0; |
||||
} |
Loading…
Reference in new issue