@ -28,12 +28,12 @@ Now, let us write a code that detects a chessboard in a new image and finds its
#.
#.
Create an empty console project. Load a test image: ::
Create an empty console project. Load a test image: ::
Mat img = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat img = imread(argv[1], IMREAD_GRAYSCALE);
#.
#.
Detect a chessboard in this image using findChessboard function. ::
Detect a chessboard in this image using findChessboard function. ::
bool found = findChessboardCorners( img, boardSize, ptvec, CV_CALIB_CB_ADAPTIVE_THRESH );
bool found = findChessboardCorners( img, boardSize, ptvec, 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*.
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*.
<< " of nr#: " << captRefrnc.get(CV_CAP_PROP_FRAME_COUNT) << endl;
<< " of nr#: " << captRefrnc.get(CAP_PROP_FRAME_COUNT) << endl;
When you are working with videos you may often want to control these values yourself. To do this there is a :hgvideo:`set <videocapture-set>` function. Its first argument remains the name of the property you want to change and there is a second of double type containing the value to be set. It will return true if it succeeds and false otherwise. Good examples for this is seeking in a video file to a given time or frame:
When you are working with videos you may often want to control these values yourself. To do this there is a :hgvideo:`set <videocapture-set>` function. Its first argument remains the name of the property you want to change and there is a second of double type containing the value to be set. It will return true if it succeeds and false otherwise. Good examples for this is seeking in a video file to a given time or frame:
..code-block:: cpp
..code-block:: cpp
captRefrnc.set(CV_CAP_PROP_POS_MSEC, 1.2); // go to the 1.2 second in the video
captRefrnc.set(CAP_PROP_POS_MSEC, 1.2); // go to the 1.2 second in the video
captRefrnc.set(CV_CAP_PROP_POS_FRAMES, 10); // go to the 10th frame of the video
captRefrnc.set(CAP_PROP_POS_FRAMES, 10); // go to the 10th frame of the video
// now a read operation would read the frame at the set position
// now a read operation would read the frame at the set position
For properties you can read and change look into the documentation of the :hgvideo:`get <videocapture-get>` and :hgvideo:`set <videocapture-set>` functions.
For properties you can read and change look into the documentation of the :hgvideo:`get <videocapture-get>` and :hgvideo:`set <videocapture-set>` functions.
@ -122,7 +122,7 @@ Here the :math:`MAX_I^2` is the maximum valid value for a pixel. In case of the
s1.convertTo(s1, CV_32F); // cannot make a square on 8 bits
s1.convertTo(s1, CV_32F); // cannot make a square on 8 bits
@ -62,8 +62,8 @@ To create a video file you just need to create an instance of the :hgvideo:`Vide
..code-block:: cpp
..code-block:: cpp
VideoCapture inputVideo(source); // Open input
VideoCapture inputVideo(source); // Open input
int ex = static_cast<int>(inputVideo.get(CV_CAP_PROP_FOURCC)); // Get Codec Type- Int form
int ex = static_cast<int>(inputVideo.get(CAP_PROP_FOURCC)); // Get Codec Type- Int form
OpenCV internally works with this integer type and expect this as its second parameter. Now to convert from the integer form to string we may use two methods: a bitwise operator and a union method. The first one extracting from an int the characters looks like (an "and" operation, some shifting and adding a 0 at the end to close the string):
OpenCV internally works with this integer type and expect this as its second parameter. Now to convert from the integer form to string we may use two methods: a bitwise operator and a union method. The first one extracting from an int the characters looks like (an "and" operation, some shifting and adding a 0 at the end to close the string):
@ -100,9 +100,9 @@ Here it is, how I use it in the sample:
..code-block:: cpp
..code-block:: cpp
VideoWriter outputVideo;
VideoWriter outputVideo;
Size S = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), //Acquire input size
Size S = Size((int) inputVideo.get(CAP_PROP_FRAME_WIDTH), //Acquire input size
Afterwards, you use the :hgvideo:`isOpened() <videowriter-isopened>` function to find out if the open operation succeeded or not. The video file automatically closes when the *VideoWriter* object is destroyed. After you open the object with success you can send the frames of the video in a sequential order by using the :hgvideo:`write<videowriter-write>` function of the class. Alternatively, you can use its overloaded operator << :
Afterwards, you use the :hgvideo:`isOpened() <videowriter-isopened>` function to find out if the open operation succeeded or not. The video file automatically closes when the *VideoWriter* object is destroyed. After you open the object with success you can send the frames of the video in a sequential order by using the :hgvideo:`write<videowriter-write>` function of the class. Alternatively, you can use its overloaded operator << :
#. For this tutorial, we will use only the Hue value for our 1-D histogram (check out the fancier code in the links above if you want to use the more standard H-S histogram, which yields better results):
#. For this tutorial, we will use only the Hue value for our 1-D histogram (check out the fancier code in the links above if you want to use the more standard H-S histogram, which yields better results):
#. Create the Trackbar to enter the kind of matching method to be used. When a change is detected the callback function **MatchingMethod** is called.
#. Create the Trackbar to enter the kind of matching method to be used. When a change is detected the callback function **MatchingMethod** is called.
@ -306,11 +306,11 @@ Explanation
+ **Mat():** Optional mask
+ **Mat():** Optional mask
#. For the first two methods ( CV\_SQDIFF and CV\_SQDIFF\_NORMED ) the best match are the lowest values. For all the others, higher values represent better matches. So, we save the corresponding value in the **matchLoc** variable:
#. For the first two methods ( TM\_SQDIFF and MT\_SQDIFF\_NORMED ) the best match are the lowest values. For all the others, higher values represent better matches. So, we save the corresponding value in the **matchLoc** variable:
printf( " ** Press 'ESC' to exit the program \n");
printf( " ** Press 'ESC' to exit the program \n");
/// Create window
/// Create window
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
namedWindow( window_name, WINDOW_AUTOSIZE );
/// Initialize arguments for the filter
/// Initialize arguments for the filter
top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
@ -150,7 +150,7 @@ Explanation
..code-block:: cpp
..code-block:: cpp
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
namedWindow( window_name, WINDOW_AUTOSIZE );
#. Now we initialize the argument that defines the size of the borders (*top*, *bottom*, *left* and *right*). We give them a value of 5% the size of *src*.
#. Now we initialize the argument that defines the size of the borders (*top*, *bottom*, *left* and *right*). We give them a value of 5% the size of *src*.
@ -83,8 +83,8 @@ After checking that the image data was loaded correctly, we want to display our
..container:: enumeratevisibleitemswithsquare
..container:: enumeratevisibleitemswithsquare
+ *CV_WINDOW_AUTOSIZE* is the only supported one if you do not use the Qt backend. In this case the window size will take up the size of the image it shows. No resize permitted!
+ *WINDOW_AUTOSIZE* is the only supported one if you do not use the Qt backend. In this case the window size will take up the size of the image it shows. No resize permitted!
+ *CV_WINDOW_NORMAL* on Qt you may use this to allow window resize. The image will resize itself according to the current window size. By using the | operator you also need to specify if you would like the image to keep its aspect ratio (*CV_WINDOW_KEEPRATIO*) or not (*CV_WINDOW_FREERATIO*).
+ *WINDOW_NORMAL* on Qt you may use this to allow window resize. The image will resize itself according to the current window size. By using the | operator you also need to specify if you would like the image to keep its aspect ratio (*WINDOW_KEEPRATIO*) or not (*WINDOW_FREERATIO*).
As you can see, :miscellaneous_transformations:`cvtColor <cvtcolor>` takes as arguments:
As you can see, :miscellaneous_transformations:`cvtColor <cvtcolor>` takes as arguments:
@ -76,7 +76,7 @@ Explanation
* a source image (*image*)
* a source image (*image*)
* a destination image (*gray_image*), in which we will save the converted image.
* a destination image (*gray_image*), in which we will save the converted image.
* an additional parameter that indicates what kind of transformation will be performed. In this case we use **CV_BGR2GRAY** (because of :readwriteimage:`imread <imread>` has BGR default channel order in case of color images).
* an additional parameter that indicates what kind of transformation will be performed. In this case we use **COLOR_BGR2GRAY** (because of :readwriteimage:`imread <imread>` has BGR default channel order in case of color images).
#. So now we have our new *gray_image* and want to save it on disk (otherwise it will get lost after the program ends). To save it, we will use a function analagous to :readwriteimage:`imread <imread>`: :readwriteimage:`imwrite <imwrite>`
#. So now we have our new *gray_image* and want to save it on disk (otherwise it will get lost after the program ends). To save it, we will use a function analagous to :readwriteimage:`imread <imread>`: :readwriteimage:`imwrite <imwrite>`
* *Type of SVM*. We choose here the type **CvSVM::C_SVC** that can be used for n-class classification (n :math:`\geq` 2). This parameter is defined in the attribute *CvSVMParams.svm_type*.
* *Type of SVM*. We choose here the type **ml::SVM::C_SVC** that can be used for n-class classification (n :math:`\geq` 2). This parameter is defined in the attribute *ml::SVM::Params.svmType*.
..note:: The important feature of the type of SVM **CvSVM::C_SVC** deals with imperfect separation of classes (i.e. when the training data is non-linearly separable). This feature is not important here since the data is linearly separable and we chose this SVM type only for being the most commonly used.
..note:: The important feature of the type of SVM **CvSVM::C_SVC** deals with imperfect separation of classes (i.e. when the training data is non-linearly separable). This feature is not important here since the data is linearly separable and we chose this SVM type only for being the most commonly used.
* *Type of SVM kernel*. We have not talked about kernel functions since they are not interesting for the training data we are dealing with. Nevertheless, let's explain briefly now the main idea behind a kernel function. It is a mapping done to the training data to improve its resemblance to a linearly separable set of data. This mapping consists of increasing the dimensionality of the data and is done efficiently using a kernel function. We choose here the type **CvSVM::LINEAR** which means that no mapping is done. This parameter is defined in the attribute *CvSVMParams.kernel_type*.
* *Type of SVM kernel*. We have not talked about kernel functions since they are not interesting for the training data we are dealing with. Nevertheless, let's explain briefly now the main idea behind a kernel function. It is a mapping done to the training data to improve its resemblance to a linearly separable set of data. This mapping consists of increasing the dimensionality of the data and is done efficiently using a kernel function. We choose here the type **ml::SVM::LINEAR** which means that no mapping is done. This parameter is defined in the attribute *ml::SVMParams.kernel_type*.
* *Termination criteria of the algorithm*. The SVM training procedure is implemented solving a constrained quadratic optimization problem in an **iterative** fashion. Here we specify a maximum number of iterations and a tolerance error so we allow the algorithm to finish in less number of steps even if the optimal hyperplane has not been computed yet. This parameter is defined in a structure :oldbasicstructures:`cvTermCriteria <cvtermcriteria>`.
* *Termination criteria of the algorithm*. The SVM training procedure is implemented solving a constrained quadratic optimization problem in an **iterative** fashion. Here we specify a maximum number of iterations and a tolerance error so we allow the algorithm to finish in less number of steps even if the optimal hyperplane has not been computed yet. This parameter is defined in a structure :oldbasicstructures:`cvTermCriteria <cvtermcriteria>`.
There are just two differences between the configuration we do here and the one that was done in the :ref:`previous tutorial <introductiontosvms>` that we use as reference.
There are just two differences between the configuration we do here and the one that was done in the :ref:`previous tutorial <introductiontosvms>` that we use as reference.
Since two types of sensor's data generators are supported (image generator and depth generator), there are two flags that should be used to set/get property of the needed generator:
Since two types of sensor's data generators are supported (image generator and depth generator), there are two flags that should be used to set/get property of the needed generator:
* CV_CAP_OPENNI_IMAGE_GENERATOR -- A flag for access to the image generator properties.
* CAP_OPENNI_IMAGE_GENERATOR -- A flag for access to the image generator properties.
* CV_CAP_OPENNI_DEPTH_GENERATOR -- A flag for access to the depth generator properties. This flag value is assumed by default if neither of the two possible values of the property is not set.
* CAP_OPENNI_DEPTH_GENERATOR -- A flag for access to the depth generator properties. This flag value is assumed by default if neither of the two possible values of the property is not set.
Some depth sensors (for example XtionPRO) do not have image generator. In order to check it you can get ``CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT`` property.
Some depth sensors (for example XtionPRO) do not have image generator. In order to check it you can get ``CAP_OPENNI_IMAGE_GENERATOR_PRESENT`` property.
Flags specifing the needed generator type must be used in combination with particular generator property. The following properties of cameras available through OpenNI interfaces are supported:
Flags specifing the needed generator type must be used in combination with particular generator property. The following properties of cameras available through OpenNI interfaces are supported:
@ -103,30 +103,30 @@ Flags specifing the needed generator type must be used in combination with parti
*
*
For image generator:
For image generator:
- ``CV_CAP_PROP_OPENNI_OUTPUT_MODE`` -- Three output modes are supported: ``CV_CAP_OPENNI_VGA_30HZ`` used by default (image generator returns images in VGA resolution with 30 FPS), ``CV_CAP_OPENNI_SXGA_15HZ`` (image generator returns images in SXGA resolution with 15 FPS) and ``CV_CAP_OPENNI_SXGA_30HZ`` (image generator returns images in SXGA resolution with 30 FPS, the mode is supported by XtionPRO Live); depth generator's maps are always in VGA resolution.
- ``CAP_PROP_OPENNI_OUTPUT_MODE`` -- Three output modes are supported: ``CAP_OPENNI_VGA_30HZ`` used by default (image generator returns images in VGA resolution with 30 FPS), ``CAP_OPENNI_SXGA_15HZ`` (image generator returns images in SXGA resolution with 15 FPS) and ``CAP_OPENNI_SXGA_30HZ`` (image generator returns images in SXGA resolution with 30 FPS, the mode is supported by XtionPRO Live); depth generator's maps are always in VGA resolution.
*
*
For depth generator:
For depth generator:
- ``CV_CAP_PROP_OPENNI_REGISTRATION`` -- Flag that registers the remapping depth map to image map by changing depth generator's view point (if the flag is ``"on"``) or sets this view point to its normal one (if the flag is ``"off"``). The registration process’s resulting images are pixel-aligned,which means that every pixel in the image is aligned to a pixel in the depth image.
- ``CAP_PROP_OPENNI_REGISTRATION`` -- Flag that registers the remapping depth map to image map by changing depth generator's view point (if the flag is ``"on"``) or sets this view point to its normal one (if the flag is ``"off"``). The registration process’s resulting images are pixel-aligned,which means that every pixel in the image is aligned to a pixel in the depth image.
Next properties are available for getting only:
Next properties are available for getting only:
- ``CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH`` -- A maximum supported depth of Kinect in mm.
- ``CAP_PROP_OPENNI_FRAME_MAX_DEPTH`` -- A maximum supported depth of Kinect in mm.
- ``CV_CAP_PROP_OPENNI_BASELINE`` -- Baseline value in mm.
- ``CAP_PROP_OPENNI_BASELINE`` -- Baseline value in mm.
- ``CV_CAP_PROP_OPENNI_FOCAL_LENGTH`` -- A focal length in pixels.
- ``CAP_PROP_OPENNI_FOCAL_LENGTH`` -- A focal length in pixels.
- ``CV_CAP_PROP_FRAME_WIDTH`` -- Frame width in pixels.
- ``CAP_PROP_FRAME_WIDTH`` -- Frame width in pixels.
- ``CV_CAP_PROP_FRAME_HEIGHT`` -- Frame height in pixels.
- ``CAP_PROP_FRAME_HEIGHT`` -- Frame height in pixels.
- ``CV_CAP_PROP_FPS`` -- Frame rate in FPS.
- ``CAP_PROP_FPS`` -- Frame rate in FPS.
*
*
Some typical flags combinations "generator type + property" are defined as single flags:
Some typical flags combinations "generator type + property" are defined as single flags:
@ -24,16 +24,16 @@ VideoCapture can retrieve the following data:
#.
#.
data given from depth generator:
data given from depth generator:
* ``CV_CAP_INTELPERC_DEPTH_MAP`` - each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth. (CV_16UC1)
* ``CAP_INTELPERC_DEPTH_MAP`` - each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth. (CV_16UC1)
* ``CV_CAP_INTELPERC_UVDEPTH_MAP`` - each pixel contains two 32-bit floating point values in the range of 0-1, representing the mapping of depth coordinates to the color coordinates. (CV_32FC2)
* ``CAP_INTELPERC_UVDEPTH_MAP`` - each pixel contains two 32-bit floating point values in the range of 0-1, representing the mapping of depth coordinates to the color coordinates. (CV_32FC2)
* ``CV_CAP_INTELPERC_IR_MAP`` - each pixel is a 16-bit integer. The value indicates the intensity of the reflected laser beam. (CV_16UC1)
* ``CAP_INTELPERC_IR_MAP`` - each pixel is a 16-bit integer. The value indicates the intensity of the reflected laser beam. (CV_16UC1)
#.
#.
data given from RGB image generator:
data given from RGB image generator:
* ``CV_CAP_INTELPERC_IMAGE`` - color image. (CV_8UC3)
* ``CAP_INTELPERC_IMAGE`` - color image. (CV_8UC3)
In order to get depth map from depth sensor use ``VideoCapture::operator >>``, e. g. ::
In order to get depth map from depth sensor use ``VideoCapture::operator >>``, e. g. ::
VideoCapture capture( CV_CAP_INTELPERC );
VideoCapture capture( CAP_INTELPERC );
for(;;)
for(;;)
{
{
Mat depthMap;
Mat depthMap;
@ -45,7 +45,7 @@ In order to get depth map from depth sensor use ``VideoCapture::operator >>``, e
For getting several data maps use ``VideoCapture::grab`` and ``VideoCapture::retrieve``, e.g. ::
For getting several data maps use ``VideoCapture::grab`` and ``VideoCapture::retrieve``, e.g. ::
VideoCapture capture(CV_CAP_INTELPERC);
VideoCapture capture(CAP_INTELPERC);
for(;;)
for(;;)
{
{
Mat depthMap;
Mat depthMap;
@ -54,9 +54,9 @@ For getting several data maps use ``VideoCapture::grab`` and ``VideoCapture::ret
Since two types of sensor's data generators are supported (image generator and depth generator), there are two flags that should be used to set/get property of the needed generator:
Since two types of sensor's data generators are supported (image generator and depth generator), there are two flags that should be used to set/get property of the needed generator:
* CV_CAP_INTELPERC_IMAGE_GENERATOR -- a flag for access to the image generator properties.
* CAP_INTELPERC_IMAGE_GENERATOR -- a flag for access to the image generator properties.
* CV_CAP_INTELPERC_DEPTH_GENERATOR -- a flag for access to the depth generator properties. This flag value is assumed by default if neither of the two possible values of the property is set.
* CAP_INTELPERC_DEPTH_GENERATOR -- a flag for access to the depth generator properties. This flag value is assumed by default if neither of the two possible values of the property is set.
For more information please refer to the example of usage intelperc_capture.cpp_ in ``opencv/samples/cpp`` folder.
For more information please refer to the example of usage intelperc_capture.cpp_ in ``opencv/samples/cpp`` folder.