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_AnaH| unicode:: Ana U+0020 Huam U+00E1 n |
||||||
.. |Author_BernatG| unicode:: Bern U+00E1 t U+0020 G U+00E1 bor |
.. |Author_BernatG| unicode:: Bern U+00E1 t U+0020 G U+00E1 bor |
||||||
.. |Author_AndreyK| unicode:: Andrey U+0020 Kamaev |
.. |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