Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
alalek committed Mar 23, 2020
2 parents 4dfa798 + 2d63861 commit 0b4c101
Show file tree
Hide file tree
Showing 25 changed files with 407 additions and 140 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ if(POLICY CMP0056)
cmake_policy(SET CMP0056 NEW) # try_compile(): link flags
endif()

if(POLICY CMP0066)
cmake_policy(SET CMP0066 NEW) # CMake 3.7: try_compile(): use per-config flags, like CMAKE_CXX_FLAGS_RELEASE
endif()

if(POLICY CMP0067)
cmake_policy(SET CMP0067 NEW) # CMake 3.8: try_compile(): honor language standard variables (like C++11)
endif()
Expand Down
10 changes: 7 additions & 3 deletions apps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
add_definitions(-D__OPENCV_BUILD=1)
add_definitions(-D__OPENCV_APPS=1)

string(REPLACE "," ";" OPENCV_INSTALL_APPS_LIST "${OPENCV_INSTALL_APPS_LIST}") # support comma-separated list (,) too

# Unified function for creating OpenCV applications:
# ocv_add_application(tgt [MODULES <m1> [<m2> ...]] SRCS <src1> [<src2> ...])
function(ocv_add_application the_target)
Expand All @@ -25,12 +27,14 @@ function(ocv_add_application the_target)
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
endif()

if(INSTALL_CREATE_DISTRIB)
if(NOT INSTALL_CREATE_DISTRIB
OR (OPENCV_INSTALL_APPS_LIST STREQUAL "all" OR ";${OPENCV_INSTALL_APPS_LIST};" MATCHES ";${the_target};")
)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
elseif(INSTALL_CREATE_DISTRIB)
if(BUILD_SHARED_LIBS)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
endif()
else()
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
endif()
endfunction()

Expand Down
4 changes: 2 additions & 2 deletions cmake/OpenCVDetectPython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ if(NOT ${found})
AND NOT DEFINED ${executable}
)
if(NOT OPENCV_SKIP_PYTHON_WARNING)
message(WARNING "CMake's 'find_host_package(PythonInterp ${__python_package_version})' founds wrong Python version:\n"
message(WARNING "CMake's 'find_host_package(PythonInterp ${__python_package_version})' found wrong Python version:\n"
"PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\n"
"PYTHON_VERSION_STRING=${PYTHON_VERSION_STRING}\n"
"Consider specify '${executable}' variable via CMake command line or environment variables\n")
"Consider providing the '${executable}' variable via CMake command line or environment variables\n")
endif()
ocv_clear_vars(PYTHONINTERP_FOUND PYTHON_EXECUTABLE PYTHON_VERSION_STRING PYTHON_VERSION_MAJOR PYTHON_VERSION_MINOR PYTHON_VERSION_PATCH)
if(NOT CMAKE_VERSION VERSION_LESS "3.12")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ OpenCV.js saves images as cv.Mat type. We use HTML canvas element to transfer cv
or in reverse. The ImageData interface can represent or set the underlying pixel data of an area of a
canvas element.

@sa Please refer to canvas docs for more details.
@note Please refer to canvas docs for more details.

First, create an ImageData obj from canvas:
@code{.js}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ use 7x6 grid. (Normally a chess board has 8x8 squares and 7x7 internal corners).
corner points and retval which will be True if pattern is obtained. These corners will be placed in
an order (from left-to-right, top-to-bottom)

@sa This function may not be able to find the required pattern in all the images. So, one good option
@note This function may not be able to find the required pattern in all the images. So, one good option
is to write the code such that, it starts the camera and check each frame for required pattern. Once
the pattern is obtained, find the corners and store it in a list. Also, provide some interval before
reading next frame so that we can adjust our chess board in different direction. Continue this
process until the required number of good patterns are obtained. Even in the example provided here, we
are not sure how many images out of the 14 given are good. Thus, we must read all the images and take only the good
ones.

@sa Instead of chess board, we can alternatively use a circular grid. In this case, we must use the function
@note Instead of chess board, we can alternatively use a circular grid. In this case, we must use the function
**cv.findCirclesGrid()** to find the pattern. Fewer images are sufficient to perform camera calibration using a circular grid.

Once we find the corners, we can increase their accuracy using **cv.cornerSubPix()**. We can also
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ A screen-shot of the window will look like this :

![image](images/matplotlib_screenshot.jpg)

@sa Plenty of plotting options are available in Matplotlib. Please refer to Matplotlib docs for more
@note Plenty of plotting options are available in Matplotlib. Please refer to Matplotlib docs for more
details. Some, we will see on the way.

__warning__
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ I got following results:

See, even image rotation doesn't affect much on this comparison.

@sa [Hu-Moments](http://en.wikipedia.org/wiki/Image_moment#Rotation_invariant_moments) are seven
@note [Hu-Moments](http://en.wikipedia.org/wiki/Image_moment#Rotation_invariant_moments) are seven
moments invariant to translation, rotation and scale. Seventh one is skew-invariant. Those values
can be found using **cv.HuMoments()** function.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ hist is same as we calculated before. But bins will have 257 elements, because N
as 0-0.99, 1-1.99, 2-2.99 etc. So final range would be 255-255.99. To represent that, they also add
256 at end of bins. But we don't need that 256. Upto 255 is sufficient.

@sa Numpy has another function, **np.bincount()** which is much faster than (around 10X)
@note Numpy has another function, **np.bincount()** which is much faster than (around 10X)
np.histogram(). So for one-dimensional histograms, you can better try that. Don't forget to set
minlength = 256 in np.bincount. For example, hist = np.bincount(img.ravel(),minlength=256)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Let's introduce the notation used to define formally a hyperplane:

where \f$\beta\f$ is known as the *weight vector* and \f$\beta_{0}\f$ as the *bias*.

@sa A more in depth description of this and hyperplanes you can find in the section 4.5 (*Separating
@note A more in depth description of this and hyperplanes you can find in the section 4.5 (*Separating
Hyperplanes*) of the book: *Elements of Statistical Learning* by T. Hastie, R. Tibshirani and J. H.
Friedman (@cite HTF01).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Describing the methods goes well beyond the purpose of this tutorial. For that I
the article introducing it. Nevertheless, you can get a good image of it by looking at the OpenCV
implementation below.

@sa
@note
SSIM is described more in-depth in the: "Z. Wang, A. C. Bovik, H. R. Sheikh and E. P.
Simoncelli, "Image quality assessment: From error visibility to structural similarity," IEEE
Transactions on Image Processing, vol. 13, no. 4, pp. 600-612, Apr. 2004." article.
Expand Down
6 changes: 3 additions & 3 deletions modules/calib3d/src/quadsubpix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ static void orderContours(const std::vector<std::vector<Point> >& contours, Poin
for(i = 0; i < n; i++)
{
size_t ni = contours[i].size();
double min_dist = std::numeric_limits<double>::max();
float min_dist = std::numeric_limits<float>::max();
for(j = 0; j < ni; j++)
{
double dist = norm(Point2f((float)contours[i][j].x, (float)contours[i][j].y) - point);
min_dist = MIN(min_dist, dist);
min_dist = (float)MIN((double)min_dist, dist);
}
order.push_back(std::pair<int, float>((int)i, (float)min_dist));
order.push_back(std::pair<int, float>((int)i, min_dist));
}

std::sort(order.begin(), order.end(), is_smaller);
Expand Down
169 changes: 90 additions & 79 deletions modules/dnn/src/layers/recurrent_layers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
float forgetBias, cellClip;
bool useCellClip, usePeephole;
bool reverse; // If true, go in negative direction along the time axis
bool bidirectional; // If true, produces both forward and reversed directions along time axis

public:

Expand All @@ -101,6 +102,7 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
{
setParamsFrom(params);

bidirectional = params.get<bool>("bidirectional", false);
if (!blobs.empty())
{
CV_Assert(blobs.size() >= 3);
Expand All @@ -110,10 +112,11 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
const Mat& Wh = blobs[0];
const Mat& Wx = blobs[1];
const Mat& bias = blobs[2];
CV_Assert(Wh.dims == 2 && Wx.dims == 2);
CV_Assert(Wh.rows == Wx.rows);
CV_Assert(Wh.rows == 4*Wh.cols);
CV_Assert(Wh.rows == (int)bias.total());
CV_CheckEQ(Wh.dims, 2, "");
CV_CheckEQ(Wx.dims, 2, "");
CV_CheckEQ(Wh.rows, Wx.rows, "");
CV_CheckEQ(Wh.rows, (1 + static_cast<int>(bidirectional))*4*Wh.cols, "");
CV_CheckEQ(Wh.rows, (int)bias.total(), "");
CV_Assert(Wh.type() == Wx.type() && Wx.type() == bias.type());

// Peephole weights.
Expand All @@ -135,6 +138,7 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
useCellClip = params.get<bool>("use_cell_clip", false);
usePeephole = params.get<bool>("use_peephole", false);
reverse = params.get<bool>("reverse", false);
CV_Assert(!reverse || !bidirectional);

allocated = false;
outTailShape.clear();
Expand Down Expand Up @@ -206,6 +210,7 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer

outResShape.push_back(_numSamples);
outResShape.insert(outResShape.end(), outTailShape_.begin(), outTailShape_.end());
outResShape.back() *= (1 + static_cast<int>(bidirectional));

size_t noutputs = produceCellOutput ? 2 : 1;
outputs.assign(noutputs, outResShape);
Expand Down Expand Up @@ -252,6 +257,7 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
outTsShape.clear();
outTsShape.push_back(numSamples);
outTsShape.insert(outTsShape.end(), outTailShape.begin(), outTailShape.end());
outTsShape.back() *= (1 + static_cast<int>(bidirectional));

allocated = true;
}
Expand All @@ -272,91 +278,96 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
outputs_arr.getMatVector(output);
internals_arr.getMatVector(internals);

const Mat &Wh = blobs[0];
const Mat &Wx = blobs[1];
const Mat &bias = blobs[2];

int numOut = Wh.size[1];

Mat hInternal = internals[0], cInternal = internals[1],
dummyOnes = internals[2], gates = internals[3];
hInternal.setTo(0.);
cInternal.setTo(0.);
dummyOnes.setTo(1.);

int numSamplesTotal = numTimeStamps*numSamples;
Mat xTs = input[0].reshape(1, numSamplesTotal);

Mat hOutTs = output[0].reshape(1, numSamplesTotal);
Mat cOutTs = produceCellOutput ? output[1].reshape(1, numSamplesTotal) : Mat();

int tsStart, tsEnd, tsInc;
if (reverse) {
tsStart = numTimeStamps - 1;
tsEnd = -1;
tsInc = -1;
}
else {
tsStart = 0;
tsEnd = numTimeStamps;
tsInc = 1;
}
for (int ts = tsStart; ts != tsEnd; ts += tsInc)
const int numDirs = 1 + static_cast<int>(bidirectional);
for (int i = 0; i < numDirs; ++i)
{
Range curRowRange(ts*numSamples, (ts + 1)*numSamples);
Mat xCurr = xTs.rowRange(curRowRange);
const Mat &Wh = blobs[0].rowRange(i * blobs[0].rows / numDirs, (i + 1) * blobs[0].rows / numDirs);
const Mat &Wx = blobs[1].rowRange(i * blobs[1].rows / numDirs, (i + 1) * blobs[1].rows / numDirs);
const Mat &bias = blobs[2].colRange(i * blobs[2].cols / numDirs, (i + 1) * blobs[2].cols / numDirs);

int numOut = Wh.size[1];

Mat hInternal = internals[0], cInternal = internals[1],
dummyOnes = internals[2], gates = internals[3];
hInternal.setTo(0.);
cInternal.setTo(0.);
dummyOnes.setTo(1.);

int numSamplesTotal = numTimeStamps*numSamples;
Mat xTs = input[0].reshape(1, numSamplesTotal);

Mat hOutTs = output[0].reshape(1, numSamplesTotal);
hOutTs = hOutTs.colRange(i * hOutTs.cols / numDirs, (i + 1) * hOutTs.cols / numDirs);
Mat cOutTs = produceCellOutput ? output[1].reshape(1, numSamplesTotal) : Mat();

int tsStart, tsEnd, tsInc;
if (reverse || i == 1) {
tsStart = numTimeStamps - 1;
tsEnd = -1;
tsInc = -1;
}
else {
tsStart = 0;
tsEnd = numTimeStamps;
tsInc = 1;
}
for (int ts = tsStart; ts != tsEnd; ts += tsInc)
{
Range curRowRange(ts*numSamples, (ts + 1)*numSamples);
Mat xCurr = xTs.rowRange(curRowRange);

gemm(xCurr, Wx, 1, gates, 0, gates, GEMM_2_T); // Wx * x_t
gemm(hInternal, Wh, 1, gates, 1, gates, GEMM_2_T); //+Wh * h_{t-1}
gemm(dummyOnes, bias, 1, gates, 1, gates); //+b
gemm(xCurr, Wx, 1, gates, 0, gates, GEMM_2_T); // Wx * x_t
gemm(hInternal, Wh, 1, gates, 1, gates, GEMM_2_T); //+Wh * h_{t-1}
gemm(dummyOnes, bias, 1, gates, 1, gates); //+b

Mat gateI = gates.colRange(0*numOut, 1*numOut);
Mat gateF = gates.colRange(1*numOut, 2*numOut);
Mat gateO = gates.colRange(2*numOut, 3*numOut);
Mat gateG = gates.colRange(3*numOut, 4*numOut);
Mat gateI = gates.colRange(0*numOut, 1*numOut);
Mat gateF = gates.colRange(1*numOut, 2*numOut);
Mat gateO = gates.colRange(2*numOut, 3*numOut);
Mat gateG = gates.colRange(3*numOut, 4*numOut);

if (forgetBias)
add(gateF, forgetBias, gateF);
if (forgetBias)
add(gateF, forgetBias, gateF);

if (usePeephole)
{
Mat gatesIF = gates.colRange(0, 2*numOut);
gemm(cInternal, blobs[3], 1, gateI, 1, gateI);
gemm(cInternal, blobs[4], 1, gateF, 1, gateF);
sigmoid(gatesIF, gatesIF);
}
else
{
Mat gatesIFO = gates.colRange(0, 3*numOut);
sigmoid(gatesIFO, gatesIFO);
}
if (usePeephole)
{
Mat gatesIF = gates.colRange(0, 2*numOut);
gemm(cInternal, blobs[3], 1, gateI, 1, gateI);
gemm(cInternal, blobs[4], 1, gateF, 1, gateF);
sigmoid(gatesIF, gatesIF);
}
else
{
Mat gatesIFO = gates.colRange(0, 3*numOut);
sigmoid(gatesIFO, gatesIFO);
}

tanh(gateG, gateG);
tanh(gateG, gateG);

//compute c_t
multiply(gateF, cInternal, gateF); // f_t (*) c_{t-1}
multiply(gateI, gateG, gateI); // i_t (*) g_t
add(gateF, gateI, cInternal); // c_t = f_t (*) c_{t-1} + i_t (*) g_t
//compute c_t
multiply(gateF, cInternal, gateF); // f_t (*) c_{t-1}
multiply(gateI, gateG, gateI); // i_t (*) g_t
add(gateF, gateI, cInternal); // c_t = f_t (*) c_{t-1} + i_t (*) g_t

if (useCellClip)
{
min(cInternal, cellClip, cInternal);
max(cInternal, -cellClip, cInternal);
}
if (usePeephole)
{
gemm(cInternal, blobs[5], 1, gateO, 1, gateO);
sigmoid(gateO, gateO);
}
if (useCellClip)
{
min(cInternal, cellClip, cInternal);
max(cInternal, -cellClip, cInternal);
}
if (usePeephole)
{
gemm(cInternal, blobs[5], 1, gateO, 1, gateO);
sigmoid(gateO, gateO);
}

//compute h_t
tanh(cInternal, hInternal);
multiply(gateO, hInternal, hInternal);
//compute h_t
tanh(cInternal, hInternal);
multiply(gateO, hInternal, hInternal);

//save results in output blobs
hInternal.copyTo(hOutTs.rowRange(curRowRange));
if (produceCellOutput)
cInternal.copyTo(cOutTs.rowRange(curRowRange));
//save results in output blobs
hInternal.copyTo(hOutTs.rowRange(curRowRange));
if (produceCellOutput)
cInternal.copyTo(cOutTs.rowRange(curRowRange));
}
}
}
};
Expand Down
Loading

0 comments on commit 0b4c101

Please sign in to comment.