Commit fb0338fb authored by Vladislav Sovrasov's avatar Vladislav Sovrasov

Merge branch 'master' into text_detector_dnn

parents 3253fe9f 374e3218
......@@ -26,14 +26,14 @@ corners) are employed.
The aruco module allows the use of Boards. The main class is the ```cv::aruco::Board``` class which defines the Board layout:
``` c++
@code{.cpp}
class Board {
public:
std::vector<std::vector<cv::Point3f> > objPoints;
cv::Ptr<cv::aruco::Dictionary> dictionary;
std::vector<int> ids;
};
```
@endcode
A object of type ```Board``` has three parameters:
- The ```objPoints``` structure is the list of corner positions in the 3d Board reference system, i.e. its layout.
......@@ -51,7 +51,7 @@ In fact, to use marker boards, a standard marker detection should be done before
The aruco module provides a specific function, ```estimatePoseBoard()```, to perform pose estimation for boards:
``` c++
@code{.cpp}
cv::Mat inputImage;
// camera parameters are read from somewhere
cv::Mat cameraMatrix, distCoeffs;
......@@ -67,7 +67,7 @@ The aruco module provides a specific function, ```estimatePoseBoard()```, to per
cv::Vec3d rvec, tvec;
int valid = cv::aruco::estimatePoseBoard(markerCorners, markerIds, board, cameraMatrix, distCoeffs, rvec, tvec);
}
```
@endcode
The parameters of estimatePoseBoard are:
......@@ -120,9 +120,9 @@ A ```GridBoard``` object can be defined using the following parameters:
This object can be easily created from these parameters using the ```cv::aruco::GridBoard::create()``` static function:
``` c++
@code{.cpp}
cv::aruco::GridBoard board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
```
@endcode
- The first and second parameters are the number of markers in the X and Y direction respectively.
- The third and fourth parameters are the marker length and the marker separation respectively. They can be provided
......@@ -136,11 +136,11 @@ through ```board.ids```, like in the ```Board``` parent class.
After creating a Grid Board, we probably want to print it and use it. A function to generate the image
of a ```GridBoard``` is provided in ```cv::aruco::GridBoard::draw()```. For example:
``` c++
@code{.cpp}
cv::Ptr<cv::aruco::GridBoard> board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
cv::Mat boardImage;
board->draw( cv::Size(600, 500), boardImage, 10, 1 );
```
@endcode
- The first parameter is the size of the output image in pixels. In this case 600x500 pixels. If this is not proportional
to the board dimensions, it will be centered on the image.
......@@ -156,13 +156,13 @@ The output image will be something like this:
A full working example of board creation is included in the ```create_board.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
"_output path_/aboard.png" -w=5 -h=7 -l=100 -s=10 -d=10
```
@endcode
Finally, a full example of board detection:
``` c++
@code{.cpp}
cv::VideoCapture inputVideo;
inputVideo.open(0);
......@@ -199,7 +199,7 @@ Finally, a full example of board detection:
if (key == 27)
break;
}
```
@endcode
Sample video:
......@@ -210,9 +210,9 @@ Sample video:
A full working example is included in the ```detect_board.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
-c="_path_"/calib.txt" "_path_/aboard.png" -w=5 -h=7 -l=100 -s=10 -d=10
```
@endcode
......@@ -255,7 +255,7 @@ internal bits are not analyzed at all and only the corner distances are evaluate
This is an example of using the ```refineDetectedMarkers()``` function:
``` c++
@code{.cpp}
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::GridBoard> board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
std::vector<int> markerIds;
......@@ -265,7 +265,7 @@ This is an example of using the ```refineDetectedMarkers()``` function:
cv::aruco::refineDetectedMarkersinputImage, board, markerCorners, markerIds, rejectedCandidates);
// After calling this function, if any new marker has been detected it will be removed from rejectedCandidates and included
// at the end of markerCorners and markerIds
```
@endcode
It must also be noted that, in some cases, if the number of detected markers in the first place is too low (for instance only
1 or 2 markers), the projections of the missing markers can be of bad quality, producing erroneous correspondences.
......
......@@ -32,7 +32,7 @@ visible in all the viewpoints.
The function to calibrate is ```calibrateCameraCharuco()```. Example:
``` c++
@code{.cpp}
cv::Ptr<aruco::CharucoBoard> board = ... // create charuco board
cv::Size imgSize = ... // camera image size
......@@ -48,7 +48,7 @@ The function to calibrate is ```calibrateCameraCharuco()```. Example:
int calibrationFlags = ... // Set calibration flags (same than in calibrateCamera() function)
double repError = cv::aruco::calibrateCameraCharuco(allCharucoCorners, allCharucoIds, board, imgSize, cameraMatrix, distCoeffs, rvecs, tvecs, calibrationFlags);
```
@endcode
The ChArUco corners and ChArUco identifiers captured on each viewpoint are stored in the vectors ```allCharucoCorners``` and ```allCharucoIds```, one element per viewpoint.
......@@ -62,9 +62,9 @@ Finally, the ```calibrationFlags``` parameter determines some of the options for
A full working example is included in the ```calibrate_camera_charuco.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
_output path_" -dp="_path_/detector_params.yml" -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10
```
@endcode
......@@ -80,7 +80,7 @@ requires the detections of an ArUco board from different viewpoints.
Example of ```calibrateCameraAruco()``` use:
``` c++
@code{.cpp}
cv::Ptr<aruco::Board> board = ... // create aruco board
cv::Size imgSize = ... // camera image size
......@@ -97,7 +97,7 @@ Example of ```calibrateCameraAruco()``` use:
int calibrationFlags = ... // Set calibration flags (same than in calibrateCamera() function)
double repError = cv::aruco::calibrateCameraAruco(allCornersConcatenated, allIdsConcatenated, markerCounterPerFrame, board, imgSize, cameraMatrix, distCoeffs, rvecs, tvecs, calibrationFlags);
```
@endcode
In this case, and contrary to the ```calibrateCameraCharuco()``` function, the detected markers on each viewpoint are concatenated in the arrays ```allCornersConcatenated``` and
```allCornersConcatenated``` (the first two parameters). The third parameter, the array ```markerCounterPerFrame```, indicates the number of marker detected on each viewpoint.
......@@ -107,6 +107,6 @@ any ```Board``` object.
A full working example is included in the ```calibrate_camera.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
"_path_/calib.txt" -w=5 -h=7 -l=100 -s=10 -d=10
```
@endcode
......@@ -19,9 +19,9 @@ a popular library for detection of square fiducial markers developed by Rafael M
> Pattern Recogn. 47, 6 (June 2014), 2280-2292. DOI=10.1016/j.patcog.2014.01.005
The aruco functionalities are included in:
``` c++
@code{.cpp}
#include <opencv2/aruco.hpp>
```
@endcode
Markers and Dictionaries
......@@ -69,11 +69,11 @@ Marker images can be generated using the ```drawMarker()``` function.
For example, lets analyze the following call:
``` c++
@code{.cpp}
cv::Mat markerImage;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::drawMarker(dictionary, 23, 200, markerImage, 1);
```
@endcode
First, the ```Dictionary``` object is created by choosing one of the predefined dictionaries in the aruco module.
Concretely, this dictionary is composed by 250 markers and a marker size of 6x6 bits (```DICT_6X6_250```).
......@@ -104,9 +104,9 @@ The generated image is:
A full working example is included in the ```create_marker.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
"/Users/Sarthak/Dropbox/OpenCV_GSoC/marker.png" -d=10 -id=1
```
@endcode
Marker Detection
------
......@@ -153,7 +153,7 @@ previous detected markers returned by ```detectMarkers()```.
An example of marker detection:
``` c++
@code{.cpp}
cv::Mat inputImage;
...
std::vector<int> markerIds;
......@@ -161,7 +161,7 @@ An example of marker detection:
cv::Ptr<cv::aruco::DetectorParameters> parameters;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
```
@endcode
The parameters of ```detectMarkers``` are:
......@@ -185,10 +185,10 @@ The next thing you probably want to do after ```detectMarkers()``` is checking t
been correctly detected. Fortunately, the aruco module provides a function to draw the detected
markers in the input image, this function is ```drawDetectedMarkers()```. For example:
``` c++
@code{.cpp}
cv::Mat outputImage
cv::aruco::drawDetectedMarkers(image, markerCorners, markerIds);
```
@endcode
- ```image``` is the input/output image where the markers will be drawn (it will normally be the same image where the markers were detected).
- ```markerCorners``` and ```markerIds``` are the structures of the detected markers in the same format
......@@ -201,7 +201,7 @@ Note that this function is only provided for visualization and its use can be pe
With these two functions we can create a basic marker detection loop to detect markers from our
camera:
``` c++
@code{.cpp}
cv::VideoCapture inputVideo;
inputVideo.open(0);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
......@@ -223,7 +223,7 @@ camera:
if (key == 27)
break;
}
```
@endcode
Note that some of the optional parameters have been omitted, like the detection parameter object or the
output vector of rejected candidates.
......@@ -231,9 +231,9 @@ output vector of rejected candidates.
A full working example is included in the ```detect_markers.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
-c="_path_/calib.txt" -d=10
```
@endcode
......@@ -262,12 +262,12 @@ information).
The aruco module provides a function to estimate the poses of all the detected markers:
``` c++
@code{.cpp}
cv::Mat cameraMatrix, distCoeffs;
...
std::vector<cv::Vec3d> rvecs, tvecs;
cv::aruco::estimatePoseSingleMarkers(corners, 0.05, cameraMatrix, distCoeffs, rvecs, tvecs);
```
@endcode
- The ```corners``` parameter is the vector of marker corners returned by the ```detectMarkers()``` function.
- The second parameter is the size of the marker side in meters or in any other unit. Note that the
......@@ -284,9 +284,9 @@ with the Z axis pointing out, as in the following image. Axis-color corresponden
The aruco module provides a function to draw the axis as in the image above, so pose estimation can be
checked:
``` c++
@code{.cpp}
cv::aruco::drawAxis(image, cameraMatrix, distCoeffs, rvec, tvec, 0.1);
```
@endcode
- ```image``` is the input/output image where the axis will be drawn (it will normally be the same image where the markers were detected).
- ```cameraMatrix``` and ```distCoeffs``` are the camera calibration parameters.
......@@ -295,7 +295,7 @@ checked:
A basic full example for pose estimation from single markers:
``` c++
@code{.cpp}
cv::VideoCapture inputVideo;
inputVideo.open(0);
......@@ -330,7 +330,7 @@ A basic full example for pose estimation from single markers:
if (key == 27)
break;
}
```
@endcode
Sample video:
......@@ -341,9 +341,9 @@ Sample video:
A full working example is included in the ```detect_markers.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
-c="_path_/calib.txt" -d=10
```
@endcode
......@@ -373,9 +373,9 @@ you can increase your system robustness:
This is the easiest way to select a dictionary. The aruco module includes a set of predefined dictionaries
of a variety of marker sizes and number of markers. For instance:
``` c++
@code{.cpp}
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
```
@endcode
DICT_6X6_250 is an example of predefined dictionary of markers with 6x6 bits and a total of 250
markers.
......@@ -389,9 +389,9 @@ The smaller the dictionary, the higher the inter-marker distance.
The dictionary can be generated automatically to adjust to the desired number of markers and bits, so that
the inter-marker distance is optimized:
``` c++
@code{.cpp}
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::generateCustomDictionary(36, 5);
```
@endcode
This will generate a customized dictionary composed by 36 markers of 5x5 bits. The process can take several
seconds, depending on the parameters (it is slower for larger dictionaries and higher number of bits).
......@@ -405,7 +405,7 @@ the ```Dictionary``` object parameters need to be assigned manually. It must be
The ```Dictionary``` parameters are:
``` c++
@code{.cpp}
class Dictionary {
public:
......@@ -416,10 +416,9 @@ The ```Dictionary``` parameters are:
...
}
@endcode
```
```bytesList``` is the array that contains all the information about the marker codes. ```markerSize``` is the size
<code>bytesList</code> is the array that contains all the information about the marker codes. ```markerSize``` is the size
of each marker dimension (for instance, 5 for markers with 5x5 bits). Finally, ```maxCorrectionBits``` is
the maximum number of erroneous bits that can be corrected during the marker detection. If this value is too
high, it can lead to a high amount of false positives.
......@@ -431,7 +430,7 @@ Fortunately, a marker can be easily transformed to this form using the static me
For example:
``` c++
@code{.cpp}
cv::aruco::Dictionary dictionary;
// markers of 6x6 bits
dictionary.markerSize = 6;
......@@ -448,8 +447,7 @@ For example:
// add the marker as a new row
dictionary.bytesList.push_back(markerCompressed);
}
```
@endcode
......
......@@ -28,9 +28,9 @@ The aruco module provides the ```cv::aruco::CharucoBoard``` class that represent
This class, as the rest of ChArUco functionalities, are defined in:
``` c++
@code{.cpp}
#include <opencv2/aruco/charuco.hpp>
```
@endcode
To define a ```CharucoBoard```, it is necesary:
......@@ -44,9 +44,9 @@ To define a ```CharucoBoard```, it is necesary:
As for the ```GridBoard``` objects, the aruco module provides a function to create ```CharucoBoard```s easily. This function
is the static function ```cv::aruco::CharucoBoard::create()``` :
``` c++
@code{.cpp}
cv::aruco::CharucoBoard board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
```
@endcode
- The first and second parameters are the number of squares in X and Y direction respectively.
- The third and fourth parameters are the length of the squares and the markers respectively. They can be provided
......@@ -57,13 +57,13 @@ The ids of each of the markers are assigned by default in ascending order and st
This can be easily customized by accessing to the ids vector through ```board.ids```, like in the ```Board``` parent class.
Once we have our ```CharucoBoard``` object, we can create an image to print it. This can be done with the
```CharucoBoard::draw()``` method:
<code>CharucoBoard::draw()</code> method:
``` c++
@code{.cpp}
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
cv::Mat boardImage;
board->draw( cv::Size(600, 500), boardImage, 10, 1 );
```
@endcode
- The first parameter is the size of the output image in pixels. In this case 600x500 pixels. If this is not proportional
to the board dimensions, it will be centered on the image.
......@@ -79,9 +79,9 @@ The output image will be something like this:
A full working example is included in the ```create_board_charuco.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
"_ output path_/chboard.png" -w=5 -h=7 -sl=200 -ml=120 -d=10
```
@endcode
ChArUco Board Detection
......@@ -102,7 +102,7 @@ ChArUco corners are interpolated from markers.
The function that detect the ChArUco corners is ```cv::aruco::interpolateCornersCharuco()``` . This example shows the whole process. First, markers are detected, and then the ChArUco corners are interpolated from these markers.
``` c++
@code{.cpp}
cv::Mat inputImage;
cv::Mat cameraMatrix, distCoeffs;
// camera parameters are read from somewhere
......@@ -120,7 +120,7 @@ The function that detect the ChArUco corners is ```cv::aruco::interpolateCorners
std::vector<int> charucoIds;
cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, inputImage, board, charucoCorners, charucoIds, cameraMatrix, distCoeffs);
}
```
@endcode
The parameters of the ```interpolateCornersCharuco()``` function are:
- ```markerCorners``` and ```markerIds```: the detected markers from ```detectMarkers()``` function.
......@@ -134,7 +134,7 @@ in the ChArUco corners.
In this case, we have call ```interpolateCornersCharuco()``` providing the camera calibration parameters. However these parameters
are optional. A similar example without these parameters would be:
``` c++
@code{.cpp}
cv::Mat inputImage;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
......@@ -151,7 +151,7 @@ are optional. A similar example without these parameters would be:
std::vector<int> charucoIds;
cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, inputImage, board, charucoCorners, charucoIds);
}
```
@endcode
If calibration parameters are provided, the ChArUco corners are interpolated by, first, estimating a rough pose from the ArUco markers
and, then, reprojecting the ChArUco corners back to the image.
......@@ -176,9 +176,9 @@ After the ChArUco corners have been interpolated, a subpixel refinement is perfo
Once we have interpolated the ChArUco corners, we would probably want to draw them to see if their detections are correct.
This can be easily done using the ```drawDetectedCornersCharuco()``` function:
``` c++
@code{.cpp}
cv::aruco::drawDetectedCornersCharuco(image, charucoCorners, charucoIds, color);
```
@endcode
- ```image``` is the image where the corners will be drawn (it will normally be the same image where the corners were detected).
- The ```outputImage``` will be a clone of ```inputImage``` with the corners drawn.
......@@ -199,7 +199,7 @@ In the presence of occlusion. like in the following image, although some corners
Finally, this is a full example of ChArUco detection (without using calibration parameters):
``` c++
@code{.cpp}
cv::VideoCapture inputVideo;
inputVideo.open(0);
......@@ -235,7 +235,7 @@ Finally, this is a full example of ChArUco detection (without using calibration
if (key == 27)
break;
}
```
@endcode
Sample video:
......@@ -246,9 +246,9 @@ Sample video:
A full working example is included in the ```detect_board_charuco.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
-c="_path_/calib.txt" -dp="_path_/detector_params.yml" -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10
```
@endcode
ChArUco Pose Estimation
------
......@@ -260,9 +260,9 @@ of the ```CharucoBoard``` is placed in the board plane with the Z axis pointing
The function for pose estimation is ```estimatePoseCharucoBoard()```:
``` c++
@code{.cpp}
cv::aruco::estimatePoseCharucoBoard(charucoCorners, charucoIds, board, cameraMatrix, distCoeffs, rvec, tvec);
```
@endcode
- The ```charucoCorners``` and ```charucoIds``` parameters are the detected charuco corners from the ```interpolateCornersCharuco()```
function.
......@@ -278,7 +278,7 @@ The axis can be drawn using ```drawAxis()``` to check the pose is correctly esti
A full example of ChArUco detection with pose estimation:
``` c++
@code{.cpp}
cv::VideoCapture inputVideo;
inputVideo.open(0);
......@@ -319,11 +319,11 @@ A full example of ChArUco detection with pose estimation:
if (key == 27)
break;
}
```
@endcode
A full working example is included in the ```detect_board_charuco.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
"_path_/calib.txt" -dp="_path_/detector_params.yml" -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10
```
@endcode
......@@ -44,11 +44,11 @@ ChArUco Diamond Creation
The image of a diamond marker can be easily created using the ```drawCharucoDiamond()``` function.
For instance:
``` c++
@code{.cpp}
cv::Mat diamondImage;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::drawCharucoDiamond(dictionary, cv::Vec4i(45,68,28,74), 200, 120, markerImage);
```
@endcode
This will create a diamond marker image with a square size of 200 pixels and a marker size of 120 pixels.
The marker ids are given in the second parameter as a ```Vec4i``` object. The order of the marker ids
......@@ -61,9 +61,9 @@ The image produced will be:
A full working example is included in the ```create_diamond.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
"_path_/mydiamond.png" -sl=200 -ml=120 -d=10 -ids=45,68,28,74
```
@endcode
ChArUco Diamond Detection
------
......@@ -71,7 +71,7 @@ ChArUco Diamond Detection
As in most cases, the detection of diamond markers requires a previous detection of ArUco markers.
After detecting markers, diamond are detected using the ```detectCharucoDiamond()``` function:
``` c++
@code{.cpp}
cv::Mat inputImage;
float squareLength = 0.40;
float markerLength = 0.25;
......@@ -89,7 +89,7 @@ After detecting markers, diamond are detected using the ```detectCharucoDiamond(
// detect diamon diamonds
cv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);
```
@endcode
The ```detectCharucoDiamond()``` function receives the original image and the previous detected marker corners and ids.
The input image is necessary to perform subpixel refinement in the ChArUco corners.
......@@ -105,14 +105,14 @@ diamond corners in ```diamondCorners```. Each id is actually an array of 4 integ
The detected diamond can be visualized using the function ```drawDetectedDiamonds()``` which simply recieves the image and the diamond
corners and ids:
``` c++
@code{.cpp}
...
std::vector<cv::Vec4i> diamondIds;
std::vector<std::vector<cv::Point2f>> diamondCorners;
cv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);
cv::aruco::drawDetectedDiamonds(inputImage, diamondCorners, diamondIds);
```
@endcode
The result is the same that the one produced by ```drawDetectedMarkers()```, but printing the four ids of the diamond:
......@@ -121,9 +121,9 @@ The result is the same that the one produced by ```drawDetectedMarkers()```, but
A full working example is included in the ```detect_diamonds.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
-c="_path_/calib.txt" -dp="_path_/detector_params.yml" -sl=0.04 -ml=0.02 -d=10
```
@endcode
ChArUco Diamond Pose Estimation
------
......@@ -131,7 +131,7 @@ ChArUco Diamond Pose Estimation
Since a ChArUco diamond is represented by its four corners, its pose can be estimated in the same way than in a single ArUco marker,
i.e. using the ```estimatePoseSingleMarkers()``` function. For instance:
``` c++
@code{.cpp}
...
std::vector<cv::Vec4i> diamondIds;
......@@ -147,7 +147,7 @@ i.e. using the ```estimatePoseSingleMarkers()``` function. For instance:
// draw axis
for(unsigned int i=0; i<rvecs.size(); i++)
cv::aruco::drawAxis(inputImage, camMatrix, distCoeffs, rvecs[i], tvecs[i], axisLength);
```
@endcode
The function will obtain the rotation and translation vector for each of the diamond marker and store them
in ```rvecs``` and ```tvecs```. Note that the diamond corners are a chessboard square corners and thus, the square length
......@@ -169,6 +169,6 @@ Sample video:
A full working example is included in the ```detect_diamonds.cpp``` inside the module samples folder.
Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like
``` c++
@code{.cpp}
-c="_output path_/calib.txt" -dp="_path_/detector_params.yml" -sl=0.04 -ml=0.02 -d=10
```
@endcode
......@@ -67,11 +67,6 @@ class CV_EXPORTS_W Saliency : public virtual Algorithm
*/
virtual ~Saliency();
/**
* \brief Create Saliency by saliency type.
*/
static Ptr<Saliency> create( const String& saliencyType );
/**
* \brief Compute the saliency
* \param image The image.
......@@ -80,12 +75,6 @@ class CV_EXPORTS_W Saliency : public virtual Algorithm
*/
CV_WRAP bool computeSaliency( InputArray image, OutputArray saliencyMap );
/**
* \brief Get the name of the specific saliency type
* \return The name of the tracker initializer
*/
CV_WRAP String getClassName() const;
protected:
virtual bool computeSaliencyImpl( InputArray image, OutputArray saliencyMap ) = 0;
......
......@@ -234,15 +234,28 @@ private:
bool templateOrdering();
bool templateReplacement( const Mat& finalBFMask, const Mat& image );
// Decision threshold adaptation and Activity control function
bool activityControl(const Mat& current_noisePixelsMask);
bool decisionThresholdAdaptation();
// changing structure
std::vector<Ptr<Mat> > backgroundModel;// The vector represents the background template T0---TK of reference paper.
// Matrices are two-channel matrix. In the first layer there are the B (background value)
// for each pixel. In the second layer, there are the C (efficacy) value for each pixel
Mat potentialBackground;// Two channel Matrix. For each pixel, in the first level there are the Ba value (potential background value)
// and in the secon level there are the Ca value, the counter for each potential value.
Mat epslonPixelsValue; // epslon threshold
Mat epslonPixelsValue;// epslon threshold
Mat activityPixelsValue;// Activity level of each pixel
//vector<Mat> noisePixelMask; // We define a ‘noise-pixel’ as a pixel that has been classified as a foreground pixel during the full resolution
Mat noisePixelMask;// We define a ‘noise-pixel’ as a pixel that has been classified as a foreground pixel during the full resolution
//detection process,however, after the low resolution detection, it has become a
// background pixel. The matrix is two-channel matrix. In the first layer there is the mask ( the identified noise-pixels are set to 1 while other pixels are 0)
// for each pixel. In the second layer, there is the value of activity level A for each pixel.
//fixed parameter
bool activityControlFlag;
bool neighborhoodCheck;
int N_DS;// Number of template to be downsampled and used in lowResolutionDetection function
CV_PROP_RW int imageWidth;// Width of input image
......@@ -257,6 +270,13 @@ private:
// long-term template, regardless of any subsequent background changes. A relatively large (eg gamma=3) will
//restrain the generation of ghosts.
uchar Ainc;// Activity Incrementation;
int Bmax;// Upper-bound value for pixel activity
int Bth;// Max activity threshold
int Binc, Bdec;// Threshold for pixel-level decision threshold (epslon) adaptation
float deltaINC, deltaDEC;// Increment-decrement value for epslon adaptation
int epslonMIN, epslonMAX;// Range values for epslon threshold
};
/************************************ Specific Objectness Specialized Classes ************************************/
......@@ -417,7 +437,7 @@ private:
int _Clr;//
static const char* _clrName[3];
// Names and paths to read model and to store results
// Names and paths to read model and to store results
std::string _modelName, _bbResDir, _trainingPath, _resultsDir;
std::vector<int> _svmSzIdxs;// Indexes of active size. It's equal to _svmFilters.size() and _svmReW1f.rows
......@@ -425,12 +445,12 @@ private:
FilterTIG _tigF;// TIG filter
Mat _svmReW1f;// Re-weight parameters learned at stage II.
// List of the rectangles' objectness value, in the same order as
// the vector<Vec4i> objectnessBoundingBox returned by the algorithm (in computeSaliencyImpl function)
// List of the rectangles' objectness value, in the same order as
// the vector<Vec4i> objectnessBoundingBox returned by the algorithm (in computeSaliencyImpl function)
std::vector<float> objectnessValues;
private:
// functions
// functions
inline static float LoG( float x, float y, float delta )
{
......@@ -438,17 +458,17 @@ private:
return -1.0f / ( (float) ( CV_PI ) * pow( delta, 4 ) ) * ( 1 + d ) * exp( d );
} // Laplacian of Gaussian
// Read matrix from binary file
// Read matrix from binary file
static bool matRead( const std::string& filename, Mat& M );
void setColorSpace( int clr = MAXBGR );
// Load trained model.
// Load trained model.
int loadTrainedModel( std::string modelName = "" );// Return -1, 0, or 1 if partial, none, or all loaded
// Get potential bounding boxes, each of which is represented by a Vec4i for (minX, minY, maxX, maxY).
// The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII().
// Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio)
// Get potential bounding boxes, each of which is represented by a Vec4i for (minX, minY, maxX, maxY).
// The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII().
// Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio)
void getObjBndBoxes( Mat &img3u, ValStructVec<float, Vec4i> &valBoxes, int numDetPerSize = 120 );
void getObjBndBoxesForSingleImage( Mat img, ValStructVec<float, Vec4i> &boxes, int numDetPerSize );
......@@ -460,7 +480,7 @@ private:
void predictBBoxSI( Mat &mag3u, ValStructVec<float, Vec4i> &valBoxes, std::vector<int> &sz, int NUM_WIN_PSZ = 100, bool fast = true );
void predictBBoxSII( ValStructVec<float, Vec4i> &valBoxes, const std::vector<int> &sz );
// Calculate the image gradient: center option as in VLFeat
// Calculate the image gradient: center option as in VLFeat
void gradientMag( Mat &imgBGR3u, Mat &mag1u );
static void gradientRGB( Mat &bgr3u, Mat &mag1u );
......@@ -479,7 +499,7 @@ private:
return abs( u[0] - v[0] ) + abs( u[1] - v[1] ) + abs( u[2] - v[2] );
}
//Non-maximal suppress
//Non-maximal suppress
static void nonMaxSup( Mat &matchCost1f, ValStructVec<float, Point> &matchCost, int NSS = 1, int maxPoint = 50, bool fast = true );
};
......
......@@ -64,6 +64,7 @@ static void help()
int main( int argc, char** argv )
{
CommandLineParser parser( argc, argv, keys );
String saliency_algorithm = parser.get<String>( 0 );
......@@ -94,13 +95,7 @@ int main( int argc, char** argv )
Mat frame;
//instantiates the specific Saliency
Ptr<Saliency> saliencyAlgorithm = Saliency::create( saliency_algorithm );
if( saliencyAlgorithm == NULL )
{
cout << "***Error in the instantiation of the saliency algorithm...***\n";
return -1;
}
Ptr<Saliency> saliencyAlgorithm;
Mat binaryMap;
Mat image;
......@@ -116,6 +111,7 @@ int main( int argc, char** argv )
if( saliency_algorithm.find( "SPECTRAL_RESIDUAL" ) == 0 )
{
Mat saliencyMap;
saliencyAlgorithm = StaticSaliencySpectralResidual::create();
if( saliencyAlgorithm->computeSaliency( image, saliencyMap ) )
{
StaticSaliencySpectralResidual spec;
......@@ -131,6 +127,7 @@ int main( int argc, char** argv )
else if( saliency_algorithm.find( "FINE_GRAINED" ) == 0 )
{
Mat saliencyMap;
saliencyAlgorithm = StaticSaliencyFineGrained::create();
if( saliencyAlgorithm->computeSaliency( image, saliencyMap ) )
{
imshow( "Saliency Map", saliencyMap );
......@@ -150,6 +147,7 @@ int main( int argc, char** argv )
else
{
saliencyAlgorithm = ObjectnessBING::create();
vector<Vec4i> saliencyMap;
saliencyAlgorithm.dynamicCast<ObjectnessBING>()->setTrainingPath( training_path );
saliencyAlgorithm.dynamicCast<ObjectnessBING>()->setBBResDir( training_path + "/Results" );
......@@ -163,8 +161,7 @@ int main( int argc, char** argv )
}
else if( saliency_algorithm.find( "BinWangApr2014" ) == 0 )
{
//Ptr<Size> size = Ptr<Size>( new Size( image.cols, image.rows ) );
saliencyAlgorithm = MotionSaliencyBinWangApr2014::create();
saliencyAlgorithm.dynamicCast<MotionSaliencyBinWangApr2014>()->setImagesize( image.cols, image.rows );
saliencyAlgorithm.dynamicCast<MotionSaliencyBinWangApr2014>()->init();
......@@ -175,13 +172,14 @@ int main( int argc, char** argv )
{
cap >> frame;
if( frame.empty() )
{
return 0;
}
cvtColor( frame, frame, COLOR_BGR2GRAY );
Mat saliencyMap;
if( saliencyAlgorithm->computeSaliency( frame, saliencyMap ) )
{
std::cout << "current frame motion saliency done" << std::endl;
}
saliencyAlgorithm->computeSaliency( frame, saliencyMap );
imshow( "image", frame );
imshow( "saliencyMap", saliencyMap * 255 );
......
......@@ -51,19 +51,6 @@ Saliency::~Saliency()
}
Ptr<Saliency> Saliency::create( const String& saliencyType )
{
if (saliencyType == "SPECTRAL_RESIDUAL")
return makePtr<StaticSaliencySpectralResidual>();
else if (saliencyType == "FINE_GRAINED")
return makePtr<StaticSaliencyFineGrained>();
else if (saliencyType == "BING")
return makePtr<ObjectnessBING>();
else if (saliencyType == "BinWangApr2014")
return makePtr<MotionSaliencyBinWangApr2014>();
return Ptr<Saliency>();
}
bool Saliency::computeSaliency( InputArray image, OutputArray saliencyMap )
{
if( image.empty() )
......@@ -72,10 +59,5 @@ bool Saliency::computeSaliency( InputArray image, OutputArray saliencyMap )
return computeSaliencyImpl( image, saliencyMap );
}
String Saliency::getClassName() const
{
return className;
}
} /* namespace saliency */
} /* namespace cv */
......@@ -61,7 +61,7 @@ namespace ppf_match_3d
* and whether it should be loaded or not
* @return Returns the matrix on successfull load
*/
CV_EXPORTS Mat loadPLYSimple(const char* fileName, int withNormals);
CV_EXPORTS Mat loadPLYSimple(const char* fileName, int withNormals = 0);
/**
* @brief Write a point cloud to PLY file
......
......@@ -55,55 +55,92 @@ void getRandomRotation(double R[9]);
void meanCovLocalPC(const float* pc, const int ws, const int point_count, double CovMat[3][3], double Mean[4]);
void meanCovLocalPCInd(const float* pc, const int* Indices, const int ws, const int point_count, double CovMat[3][3], double Mean[4]);
static std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
Mat loadPLYSimple(const char* fileName, int withNormals)
{
Mat cloud;
int numVertices=0;
int numVertices = 0;
int numCols = 3;
int has_normals = 0;
std::ifstream ifs(fileName);
if (!ifs.is_open())
{
printf("Cannot open file...\n");
return Mat();
}
CV_Error(Error::StsError, String("Error opening input file: ") + String(fileName) + "\n");
std::string str;
while (str.substr(0, 10) !="end_header")
while (str.substr(0, 10) != "end_header")
{
std::string entry = str.substr(0, 14);
if (entry == "element vertex")
std::vector<std::string> tokens = split(str,' ');
if (tokens.size() == 3)
{
numVertices = atoi(str.substr(15, str.size()-15).c_str());
if (tokens[0] == "element" && tokens[1] == "vertex")
{
numVertices = atoi(tokens[2].c_str());
}
else if (tokens[0] == "property")
{
if (tokens[2] == "nx" || tokens[2] == "normal_x")
{
has_normals = -1;
numCols += 3;
}
else if (tokens[2] == "r" || tokens[2] == "red")
{
//has_color = true;
numCols += 3;
}
else if (tokens[2] == "a" || tokens[2] == "alpha")
{
//has_alpha = true;
numCols += 1;
}
}
}
else if (tokens.size() > 1 && tokens[0] == "format" && tokens[1] != "ascii")
CV_Error(Error::StsBadArg, String("Cannot read file, only ascii ply format is currently supported..."));
std::getline(ifs, str);
}
withNormals &= has_normals;
if (withNormals)
cloud=Mat(numVertices, 6, CV_32FC1);
else
cloud=Mat(numVertices, 3, CV_32FC1);
cloud = Mat(numVertices, withNormals ? 6 : 3, CV_32FC1);
for (int i = 0; i < numVertices; i++)
{
float* data = cloud.ptr<float>(i);
int col = 0;
for (; col < withNormals ? 6 : 3; ++col)
{
ifs >> data[col];
}
for (; col < numCols; ++col)
{
float tmp;
ifs >> tmp;
}
if (withNormals)
{
ifs >> data[0] >> data[1] >> data[2] >> data[3] >> data[4] >> data[5];
// normalize to unit norm
double norm = sqrt(data[3]*data[3] + data[4]*data[4] + data[5]*data[5]);
if (norm>0.00001)
{
data[3]/=(float)norm;
data[4]/=(float)norm;
data[5]/=(float)norm;
data[3]/=static_cast<float>(norm);
data[4]/=static_cast<float>(norm);
data[5]/=static_cast<float>(norm);
}
}
else
{
ifs >> data[0] >> data[1] >> data[2];
}
}
//cloud *= 5.0f;
......
......@@ -538,8 +538,66 @@ at each window location.
CV_EXPORTS_W Ptr<OCRBeamSearchDecoder::ClassifierCallback> loadOCRBeamSearchClassifierCNN(const String& filename);
/** @brief OCRHolisticWordRecognizer class provides the functionallity of segmented wordspotting.
* Given a predefined vocabulary , a DictNet is employed to select the most probable
* word given an input image.
*
* DictNet is described in detail in:
* Max Jaderberg et al.: Reading Text in the Wild with Convolutional Neural Networks, IJCV 2015
* http://arxiv.org/abs/1412.1842
*/
class CV_EXPORTS OCRHolisticWordRecognizer : public BaseOCR
{
public:
virtual void run(Mat& image,
std::string& output_text,
std::vector<Rect>* component_rects = NULL,
std::vector<std::string>* component_texts = NULL,
std::vector<float>* component_confidences = NULL,
int component_level = OCR_LEVEL_WORD) = 0;
/** @brief Recognize text using a segmentation based word-spotting/classifier cnn.
Takes image on input and returns recognized text in the output_text parameter. Optionally
provides also the Rects for individual text elements found (e.g. words), and the list of those
text elements with their confidence values.
@param image Input image CV_8UC1 or CV_8UC3
@param mask is totally ignored and is only available for compatibillity reasons
@param output_text Output text of the the word spoting, always one that exists in the dictionary.
@param component_rects Not applicable for word spotting can be be NULL if not, a single elemnt will
be put in the vector.
@param component_texts Not applicable for word spotting can be be NULL if not, a single elemnt will
be put in the vector.
@param component_confidences Not applicable for word spotting can be be NULL if not, a single elemnt will
be put in the vector.
@param component_level must be OCR_LEVEL_WORD.
*/
virtual void run(Mat& image,
Mat& mask,
std::string& output_text,
std::vector<Rect>* component_rects = NULL,
std::vector<std::string>* component_texts = NULL,
std::vector<float>* component_confidences = NULL,
int component_level = OCR_LEVEL_WORD) = 0;
/** @brief Creates an instance of the OCRHolisticWordRecognizer class.
*/
static Ptr<OCRHolisticWordRecognizer> create(const std::string &archFilename,
const std::string &weightsFilename,
const std::string &wordsFilename);
};
//! @}
}
}
}} // cv::text::
#endif // _OPENCV_TEXT_OCR_HPP_
/*
* dictnet_demo.cpp
*
* Demonstrates simple use of the holistic word classifier in C++
*
* Created on: June 26, 2016
* Author: Anguelos Nicolaou <anguelos.nicolaou AT gmail.com>
*/
#include "opencv2/text.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <sstream>
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::text;
inline void printHelp()
{
cout << " Demo of wordspotting CNN for text recognition." << endl;
cout << " Max Jaderberg et al.: Reading Text in the Wild with Convolutional Neural Networks, IJCV 2015"<<std::endl<<std::endl;
cout << " Usage: program <input_image>" << endl;
cout << " Caffe Model files (dictnet_vgg.caffemodel, dictnet_vgg_deploy.prototxt, dictnet_vgg_labels.txt)"<<endl;
cout << " must be in the current directory." << endl << endl;
cout << " Obtaining Caffe Model files in linux shell:"<<endl;
cout << " wget http://nicolaou.homouniversalis.org/assets/vgg_text/dictnet_vgg.caffemodel"<<endl;
cout << " wget http://nicolaou.homouniversalis.org/assets/vgg_text/dictnet_vgg_deploy.prototxt"<<endl;
cout << " wget http://nicolaou.homouniversalis.org/assets/vgg_text/dictnet_vgg_labels.txt"<<endl<<endl;
}
int main(int argc, const char * argv[])
{
if (argc != 2)
{
printHelp();
exit(1);
}
Mat image = imread(argv[1], IMREAD_GRAYSCALE);
cout << "Read image (" << argv[1] << "): " << image.size << ", channels: " << image.channels() << ", depth: " << image.depth() << endl;
if (image.empty())
{
printHelp();
exit(1);
}
Ptr<OCRHolisticWordRecognizer> wordSpotter = OCRHolisticWordRecognizer::create("dictnet_vgg_deploy.prototxt", "dictnet_vgg.caffemodel", "dictnet_vgg_labels.txt");
std::string word;
vector<float> confs;
wordSpotter->run(image, word, 0, 0, &confs);
cout << "Detected word: '" << word << "', confidence: " << confs[0] << endl;
}
#include "precomp.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/dnn.hpp"
#include <fstream>
using namespace std;
namespace cv { namespace text {
class OCRHolisticWordRecognizerImpl : public OCRHolisticWordRecognizer
{
private:
dnn::Net net;
vector<string> words;
public:
OCRHolisticWordRecognizerImpl(const string &archFilename, const string &weightsFilename, const string &wordsFilename)
{
net = dnn::readNetFromCaffe(archFilename, weightsFilename);
std::ifstream in(wordsFilename.c_str());
if (!in)
{
CV_Error(Error::StsError, "Could not read Labels from file");
}
std::string line;
while (std::getline(in, line))
words.push_back(line);
CV_Assert(getClassCount() == words.size());
}
void run(Mat& image, std::string& output_text, std::vector<Rect>* component_rects=NULL, std::vector<std::string>* component_texts=NULL, std::vector<float>* component_confidences=NULL, int component_level=0)
{
CV_Assert(component_level==OCR_LEVEL_WORD); //Componnents not applicable for word spotting
double confidence;
output_text = classify(image, confidence);
if(component_rects!=NULL){
component_rects->resize(1);
(*component_rects)[0]=Rect(0,0,image.size().width,image.size().height);
}
if(component_texts!=NULL){
component_texts->resize(1);
(*component_texts)[0] = output_text;
}
if(component_confidences!=NULL){
component_confidences->resize(1);
(*component_confidences)[0] = float(confidence);
}
}
void run(Mat& image, Mat& mask, std::string& output_text, std::vector<Rect>* component_rects=NULL, std::vector<std::string>* component_texts=NULL, std::vector<float>* component_confidences=NULL, int component_level=0)
{
//Mask is ignored because the CNN operates on a full image
CV_Assert(mask.cols == image.cols && mask.rows == image.rows);
this->run(image, output_text, component_rects, component_texts, component_confidences, component_level);
}
protected:
Size getPerceptiveField() const
{
return Size(100, 32);
}
size_t getClassCount()
{
int id = net.getLayerId("prob");
dnn::MatShape inputShape;
inputShape.push_back(1);
inputShape.push_back(1);
inputShape.push_back(getPerceptiveField().height);
inputShape.push_back(getPerceptiveField().width);
vector<dnn::MatShape> inShapes, outShapes;
net.getLayerShapes(inputShape, id, inShapes, outShapes);
CV_Assert(outShapes.size() == 1 && outShapes[0].size() == 4);
CV_Assert(outShapes[0][0] == 1 && outShapes[0][2] == 1 && outShapes[0][3] == 1);
return outShapes[0][1];
}
string classify(InputArray image, double & conf)
{
CV_Assert(image.channels() == 1 && image.depth() == CV_8U);
Mat resized;
resize(image, resized, getPerceptiveField());
Mat blob = dnn::blobFromImage(resized);
net.setInput(blob, "data");
Mat prob = net.forward("prob");
CV_Assert(prob.dims == 4 && !prob.empty() && prob.size[1] == (int)getClassCount());
int idx[4] = {0};
minMaxIdx(prob, 0, &conf, 0, idx);
CV_Assert(0 <= idx[1] && idx[1] < (int)words.size());
return words[idx[1]];
}
};
Ptr<OCRHolisticWordRecognizer> OCRHolisticWordRecognizer::create(const string &archFilename, const string &weightsFilename, const string &wordsFilename)
{
return makePtr<OCRHolisticWordRecognizerImpl>(archFilename, weightsFilename, wordsFilename);
}
}} // cv::text::
......@@ -1236,12 +1236,12 @@ public:
*/
void write(FileStorage& /*fs*/) const;
double detect_thresh; //!< detection confidence threshold
double sigma; //!< gaussian kernel bandwidth
double lambda; //!< regularization
double interp_factor; //!< linear interpolation factor for adaptation
double output_sigma_factor; //!< spatial bandwidth (proportional to target)
double pca_learning_rate; //!< compression learning rate
float detect_thresh; //!< detection confidence threshold
float sigma; //!< gaussian kernel bandwidth
float lambda; //!< regularization
float interp_factor; //!< linear interpolation factor for adaptation
float output_sigma_factor; //!< spatial bandwidth (proportional to target)
float pca_learning_rate; //!< compression learning rate
bool resize; //!< activate the resize feature to improve the processing speed
bool split_coeff; //!< split the training coefficients into two matrices
bool wrap_kernel; //!< wrap around the kernel values
......
......@@ -117,6 +117,7 @@ int main( int argc, char** argv ){
bool initialized = false;
int frameCounter = 0;
int64 timeTotal = 0;
for ( ;; )
{
......@@ -142,11 +143,14 @@ int main( int argc, char** argv ){
}
else if( initialized )
{
int64 frameTime = getTickCount();
//updates the tracker
if( tracker->update( frame, boundingBox ) )
{
rectangle( image, boundingBox, Scalar( 255, 0, 0 ), 2, 1 );
}
frameTime = getTickCount() - frameTime;
timeTotal += frameTime;
}
imshow( "Tracking API", image );
frameCounter++;
......@@ -159,5 +163,8 @@ int main( int argc, char** argv ){
paused = !paused;
}
double s = frameCounter / (timeTotal / getTickFrequency());
printf("FPS: %f\n", s);
return 0;
}
This diff is collapsed.
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#define LOCAL_SIZE_X 64
#define BLOCK_SIZE_X 3
__kernel void tmm(__global float *A, int m, int n, float alpha, __global float *D)
{
int lidX = get_local_id(0);
uint lsizeX = get_local_size(0);
uint matI = get_group_id(1);
uint matJ = get_group_id(0);
if (matI < matJ)
return;
__local float4 a[LOCAL_SIZE_X], b[LOCAL_SIZE_X];
float4 result;
__local uint cnt;
result = 0;
cnt = 0;
barrier(CLK_LOCAL_MEM_FENCE);
do {
// load block data to SLM.
int global_block_base = (lidX + cnt * lsizeX) * BLOCK_SIZE_X;
float4 pa[BLOCK_SIZE_X], pb[BLOCK_SIZE_X];
#pragma unroll
for(uint j = 0; j < BLOCK_SIZE_X && (cnt * lsizeX + lidX) * BLOCK_SIZE_X < n / 4; j++) {
pa[j] = *(__global float4*)&A[matI * n + (global_block_base + j) * 4];
if (matI != matJ)
pb[j] = *(__global float4*)&A[matJ * n + (global_block_base + j) * 4];
else
pb[j] = pa[j];
}
// zero the data out-of-boundary.
if (global_block_base + BLOCK_SIZE_X - 1 >= n/4) {
#pragma unroll
for(int i = 0; i < BLOCK_SIZE_X; i++) {
if (global_block_base + i >= n/4)
pb[i] = 0;
}
}
pb[0] *= pa[0];
for(int j = 1; j < BLOCK_SIZE_X; j++)
pb[0] = fma(pb[j], pa[j], pb[0]);
b[lidX] = pb[0];
barrier(CLK_LOCAL_MEM_FENCE);
// perform reduce add
for(int offset = LOCAL_SIZE_X / 2; offset > 0; offset >>= 1) {
if (lidX < offset)
b[lidX] += b[(lidX + offset)];
barrier(CLK_LOCAL_MEM_FENCE);
}
if (lidX == 0) {
result += b[0];
cnt++;
}
barrier(CLK_LOCAL_MEM_FENCE);
} while(cnt * BLOCK_SIZE_X * lsizeX < n / 4);
if (lidX == 0) {
float ret = (result.s0 + result.s1 + result.s2 + result.s3) * alpha;
D[matI * m + matJ] = ret;
if (matI != matJ)
D[matJ * m + matI] = ret;
}
}
......@@ -42,6 +42,7 @@
#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__
#include "cvconfig.h"
#include "opencv2/tracking.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/ocl.hpp"
......@@ -50,7 +51,7 @@
namespace cv
{
extern const double ColorNames[][10];
extern const float ColorNames[][10];
namespace tracking {
......
This diff is collapsed.
......@@ -63,10 +63,10 @@ TEST(KCF_Parameters, IO)
{
TrackerKCF::Params parameters;
parameters.sigma = 0.3;
parameters.lambda = 0.02;
parameters.interp_factor = 0.08;
parameters.output_sigma_factor = 1.0/ 32.0;
parameters.sigma = 0.3f;
parameters.lambda = 0.02f;
parameters.interp_factor = 0.08f;
parameters.output_sigma_factor = 1.0f/ 32.0f;
parameters.resize=false;
parameters.max_patch_size=90*90;
parameters.split_coeff=false;
......@@ -75,7 +75,7 @@ TEST(KCF_Parameters, IO)
parameters.desc_pca = TrackerKCF::GRAY;
parameters.compress_feature=false;
parameters.compressed_size=3;
parameters.pca_learning_rate=0.2;
parameters.pca_learning_rate=0.2f;
FileStorage fsWriter("parameters.xml", FileStorage::WRITE + FileStorage::MEMORY);
parameters.write(fsWriter);
......
......@@ -605,7 +605,7 @@ public:
* @brief Weights (multiplicative constants) that linearly stretch individual axes of the feature space
* (x,y = position; L,a,b = color in CIE Lab space; c = contrast. e = entropy)
*/
CV_WRAP virtual float getWeightConstrast() const = 0;
CV_WRAP virtual float getWeightContrast() const = 0;
/**
* @brief Weights (multiplicative constants) that linearly stretch individual axes of the feature space
* (x,y = position; L,a,b = color in CIE Lab space; c = contrast. e = entropy)
......@@ -925,6 +925,26 @@ public:
bool useProvidedKeypoints=false ) = 0;
};
/** @brief Estimates cornerness for prespecified KeyPoints using the FAST algorithm
@param image grayscale image where keypoints (corners) are detected.
@param keypoints keypoints which should be tested to fit the FAST criteria. Keypoints not beeing
detected as corners are removed.
@param threshold threshold on difference between intensity of the central pixel and pixels of a
circle around this pixel.
@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners
(keypoints).
@param type one of the three neighborhoods as defined in the paper:
FastFeatureDetector::TYPE_9_16, FastFeatureDetector::TYPE_7_12,
FastFeatureDetector::TYPE_5_8
Detects corners using the FAST algorithm by @cite Rosten06 .
*/
CV_EXPORTS void FASTForPointSet( InputArray image, CV_IN_OUT std::vector<KeyPoint>& keypoints,
int threshold, bool nonmaxSuppression=true, int type=FastFeatureDetector::TYPE_9_16);
//! @}
}
......
This diff is collapsed.
......@@ -137,7 +137,7 @@ namespace cv
float getWeightL() const { return mSampler->getWeightL(); }
float getWeightA() const { return mSampler->getWeightA(); }
float getWeightB() const { return mSampler->getWeightB(); }
float getWeightConstrast() const { return mSampler->getWeightConstrast(); }
float getWeightContrast() const { return mSampler->getWeightContrast(); }
float getWeightEntropy() const { return mSampler->getWeightEntropy(); }
std::vector<Point2f> getSamplingPoints() const { return mSampler->getSamplingPoints(); }
......
......@@ -128,7 +128,7 @@ namespace cv
float getWeightL() const { return mWeights[L_IDX]; }
float getWeightA() const { return mWeights[A_IDX]; }
float getWeightB() const { return mWeights[B_IDX]; }
float getWeightConstrast() const { return mWeights[CONTRAST_IDX]; }
float getWeightContrast() const { return mWeights[CONTRAST_IDX]; }
float getWeightEntropy() const { return mWeights[ENTROPY_IDX]; }
std::vector<Point2f> getSamplingPoints() const
......
......@@ -103,7 +103,7 @@ namespace cv
virtual float getWeightL() const = 0;
virtual float getWeightA() const = 0;
virtual float getWeightB() const = 0;
virtual float getWeightConstrast() const = 0;
virtual float getWeightContrast() const = 0;
virtual float getWeightEntropy() const = 0;
virtual std::vector<Point2f> getSamplingPoints() const = 0;
......
......@@ -89,7 +89,7 @@ namespace cv
const Mat& points2, int idx2)
{
float distance = computeDistance(distancefunction, points1, idx1, points2, idx2);
return exp(-alpha + distance * distance);
return exp(-alpha * distance * distance);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment