Merge branch 'Itseez-2.4' into Feature_3692_2.4

pull/2769/head
Hernan Badino 11 years ago
commit 8a3b93773d
  1. 5
      modules/core/doc/operations_on_arrays.rst
  2. 2
      modules/core/include/opencv2/core/core.hpp
  3. 14
      modules/core/src/matrix.cpp
  4. 91
      modules/core/test/test_math.cpp
  5. 23
      modules/highgui/src/window_w32.cpp
  6. 51
      modules/imgproc/doc/geometric_transformations.rst
  7. 6
      modules/imgproc/doc/miscellaneous_transformations.rst
  8. 2
      modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst
  9. 7
      modules/imgproc/src/filter.cpp
  10. 2
      modules/imgproc/src/smooth.cpp
  11. 6
      modules/legacy/src/calibfilter.cpp
  12. 52
      modules/video/src/bgfg_gaussmix2.cpp
  13. 2
      samples/cpp/kmeans.cpp

@ -1252,11 +1252,12 @@ gemm
----
Performs generalized matrix multiplication.
.. ocv:function:: void gemm( InputArray src1, InputArray src2, double alpha, InputArray src3, double gamma, OutputArray dst, int flags=0 )
.. ocv:function:: void gemm( InputArray src1, InputArray src2, double alpha, InputArray src3, double beta, OutputArray dst, int flags=0 )
.. ocv:pyfunction:: cv2.gemm(src1, src2, alpha, src3, gamma[, dst[, flags]]) -> dst
.. ocv:pyfunction:: cv2.gemm(src1, src2, alpha, src3, beta[, dst[, flags]]) -> dst
.. ocv:cfunction:: void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC=0)
.. ocv:pyoldfunction:: cv.GEMM(src1, src2, alpha, src3, beta, dst, tABC=0)-> None
:param src1: first multiplied input matrix that should have ``CV_32FC1``, ``CV_64FC1``, ``CV_32FC2``, or ``CV_64FC2`` type.

@ -2319,7 +2319,7 @@ CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val=0);
//! implements generalized matrix product algorithm GEMM from BLAS
CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha,
InputArray src3, double gamma, OutputArray dst, int flags=0);
InputArray src3, double beta, OutputArray dst, int flags=0);
//! multiplies matrix by its transposition from the left or from the right
CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa,
InputArray delta=noArray(),

@ -2691,16 +2691,18 @@ double cv::kmeans( InputArray _data, int K,
int flags, OutputArray _centers )
{
const int SPP_TRIALS = 3;
Mat data = _data.getMat();
bool isrow = data.rows == 1 && data.channels() > 1;
int N = !isrow ? data.rows : data.cols;
int dims = (!isrow ? data.cols : 1)*data.channels();
int type = data.depth();
Mat data0 = _data.getMat();
bool isrow = data0.rows == 1 && data0.channels() > 1;
int N = !isrow ? data0.rows : data0.cols;
int dims = (!isrow ? data0.cols : 1)*data0.channels();
int type = data0.depth();
attempts = std::max(attempts, 1);
CV_Assert( data.dims <= 2 && type == CV_32F && K > 0 );
CV_Assert( data0.dims <= 2 && type == CV_32F && K > 0 );
CV_Assert( N >= K );
Mat data(N, dims, CV_32F, data0.data, isrow ? dims * sizeof(float) : static_cast<size_t>(data0.step));
_bestLabels.create(N, 1, CV_32S, -1, true);
Mat _labels, best_labels = _bestLabels.getMat();

@ -2512,6 +2512,15 @@ TEST(Core_SVD, flt)
// TODO: eigenvv, invsqrt, cbrt, fastarctan, (round, floor, ceil(?)),
enum
{
MAT_N_DIM_C1,
MAT_N_1_CDIM,
MAT_1_N_CDIM,
MAT_N_DIM_C1_NONCONT,
MAT_N_1_CDIM_NONCONT,
VECTOR
};
class CV_KMeansSingularTest : public cvtest::BaseTest
{
@ -2519,7 +2528,7 @@ public:
CV_KMeansSingularTest() {}
~CV_KMeansSingularTest() {}
protected:
void run(int)
void run(int inVariant)
{
int i, iter = 0, N = 0, N0 = 0, K = 0, dims = 0;
Mat labels;
@ -2531,20 +2540,70 @@ protected:
for( iter = 0; iter < maxIter; iter++ )
{
ts->update_context(this, iter, true);
dims = rng.uniform(1, MAX_DIM+1);
dims = rng.uniform(inVariant == MAT_1_N_CDIM ? 2 : 1, MAX_DIM+1);
N = rng.uniform(1, MAX_POINTS+1);
N0 = rng.uniform(1, MAX(N/10, 2));
K = rng.uniform(1, N+1);
Mat data0(N0, dims, CV_32F);
rng.fill(data0, RNG::UNIFORM, -1, 1);
if (inVariant == VECTOR)
{
dims = 2;
Mat data(N, dims, CV_32F);
for( i = 0; i < N; i++ )
data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
std::vector<cv::Point2f> data0(N0);
rng.fill(data0, RNG::UNIFORM, -1, 1);
std::vector<cv::Point2f> data(N);
for( i = 0; i < N; i++ )
data[i] = data0[rng.uniform(0, N0)];
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
5, KMEANS_PP_CENTERS);
}
else
{
Mat data0(N0, dims, CV_32F);
rng.fill(data0, RNG::UNIFORM, -1, 1);
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
5, KMEANS_PP_CENTERS);
Mat data;
switch (inVariant)
{
case MAT_N_DIM_C1:
data.create(N, dims, CV_32F);
for( i = 0; i < N; i++ )
data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
break;
case MAT_N_1_CDIM:
data.create(N, 1, CV_32FC(dims));
for( i = 0; i < N; i++ )
memcpy(data.ptr(i), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
break;
case MAT_1_N_CDIM:
data.create(1, N, CV_32FC(dims));
for( i = 0; i < N; i++ )
memcpy(data.data + i * dims * sizeof(float), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
break;
case MAT_N_DIM_C1_NONCONT:
data.create(N, dims + 5, CV_32F);
data = data(Range(0, N), Range(0, dims));
for( i = 0; i < N; i++ )
data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
break;
case MAT_N_1_CDIM_NONCONT:
data.create(N, 3, CV_32FC(dims));
data = data.colRange(0, 1);
for( i = 0; i < N; i++ )
memcpy(data.ptr(i), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
break;
}
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
5, KMEANS_PP_CENTERS);
}
Mat hist(K, 1, CV_32S, Scalar(0));
for( i = 0; i < N; i++ )
@ -2568,7 +2627,19 @@ protected:
}
};
TEST(Core_KMeans, singular) { CV_KMeansSingularTest test; test.safe_run(); }
TEST(Core_KMeans, singular) { CV_KMeansSingularTest test; test.safe_run(MAT_N_DIM_C1); }
CV_ENUM(KMeansInputVariant, MAT_N_DIM_C1, MAT_N_1_CDIM, MAT_1_N_CDIM, MAT_N_DIM_C1_NONCONT, MAT_N_1_CDIM_NONCONT, VECTOR)
typedef testing::TestWithParam<KMeansInputVariant> Core_KMeans_InputVariants;
TEST_P(Core_KMeans_InputVariants, singular)
{
CV_KMeansSingularTest test;
test.safe_run(GetParam());
}
INSTANTIATE_TEST_CASE_P(AllVariants, Core_KMeans_InputVariants, KMeansInputVariant::all());
TEST(CovariationMatrixVectorOfMat, accuracy)
{

@ -1436,8 +1436,6 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
if( window->on_mouse )
{
POINT pt;
RECT rect;
SIZE size = {0,0};
int flags = (wParam & MK_LBUTTON ? CV_EVENT_FLAG_LBUTTON : 0)|
(wParam & MK_RBUTTON ? CV_EVENT_FLAG_RBUTTON : 0)|
@ -1463,12 +1461,23 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
pt.x = GET_X_LPARAM( lParam );
pt.y = GET_Y_LPARAM( lParam );
GetClientRect( window->hwnd, &rect );
icvGetBitmapData( window, &size, 0, 0 );
if (window->flags & CV_WINDOW_AUTOSIZE)
{
// As user can't change window size, do not scale window coordinates. Underlying windowing system
// may prevent full window from being displayed and in this case coordinates should not be scaled.
window->on_mouse( event, pt.x, pt.y, flags, window->on_mouse_param );
} else {
// Full window is displayed using different size. Scale coordinates to match underlying positions.
RECT rect;
SIZE size = {0, 0};
GetClientRect( window->hwnd, &rect );
icvGetBitmapData( window, &size, 0, 0 );
window->on_mouse( event, pt.x*size.cx/MAX(rect.right - rect.left,1),
pt.y*size.cy/MAX(rect.bottom - rect.top,1), flags,
window->on_mouse_param );
window->on_mouse( event, pt.x*size.cx/MAX(rect.right - rect.left,1),
pt.y*size.cy/MAX(rect.bottom - rect.top,1), flags,
window->on_mouse_param );
}
}
break;

@ -256,6 +256,57 @@ The function computes an inverse affine transformation represented by
The result is also a
:math:`2 \times 3` matrix of the same type as ``M`` .
LinearPolar
-----------
Remaps an image to polar space.
.. ocv:cfunction:: void cvLinearPolar( const CvArr* src, CvArr* dst, CvPoint2D32f center, double maxRadius, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS )
:param src: Source image
:param dst: Destination image
:param center: The transformation center;
:param maxRadius: Inverse magnitude scale parameter. See below
:param flags: A combination of interpolation methods and the following optional flags:
* **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero
* **CV_WARP_INVERSE_MAP** See below
The function ``cvLinearPolar`` transforms the source image using the following transformation:
*
Forward transformation (``CV_WARP_INVERSE_MAP`` is not set):
.. math::
dst( \phi , \rho ) = src(x,y)
*
Inverse transformation (``CV_WARP_INVERSE_MAP`` is set):
.. math::
dst(x,y) = src( \phi , \rho )
where
.. math::
\rho = (src.width/maxRadius) \cdot \sqrt{x^2 + y^2} , \phi =atan(y/x)
The function can not operate in-place.
.. note::
* An example using the LinearPolar operation can be found at opencv_source_code/samples/c/polar_transforms.c
LogPolar

@ -504,7 +504,7 @@ Fills a connected component with the given color.
:param image: Input/output 1- or 3-channel, 8-bit, or floating-point image. It is modified by the function unless the ``FLOODFILL_MASK_ONLY`` flag is set in the second variant of the function. See the details below.
:param mask: (For the second function only) Operation mask that should be a single-channel 8-bit image, 2 pixels wider and 2 pixels taller. The function uses and updates the mask, so you take responsibility of initializing the ``mask`` content. Flood-filling cannot go across non-zero pixels in the mask. For example, an edge detector output can be used as a mask to stop filling at edges. It is possible to use the same mask in multiple calls to the function to make sure the filled area does not overlap.
:param mask: Operation mask that should be a single-channel 8-bit image, 2 pixels wider and 2 pixels taller than ``image``. Since this is both an input and output parameter, you must take responsibility of initializing it. Flood-filling cannot go across non-zero pixels in the input mask. For example, an edge detector output can be used as a mask to stop filling at edges. On output, pixels in the mask corresponding to filled pixels in the image are set to 1 or to the a value specified in ``flags`` as described below. It is therefore possible to use the same mask in multiple calls to the function to make sure the filled areas do not overlap.
.. note:: Since the mask is larger than the filled image, a pixel :math:`(x, y)` in ``image`` corresponds to the pixel :math:`(x+1, y+1)` in the ``mask`` .
@ -518,11 +518,11 @@ Fills a connected component with the given color.
:param rect: Optional output parameter set by the function to the minimum bounding rectangle of the repainted domain.
:param flags: Operation flags. Lower bits contain a connectivity value, 4 (default) or 8, used within the function. Connectivity determines which neighbors of a pixel are considered. Upper bits can be 0 or a combination of the following flags:
:param flags: Operation flags. The first 8 bits contain a connectivity value. The default value of 4 means that only the four nearest neighbor pixels (those that share an edge) are considered. A connectivity value of 8 means that the eight nearest neighbor pixels (those that share a corner) will be considered. The next 8 bits (8-16) contain a value between 1 and 255 with which to fill the ``mask`` (the default value is 1). For example, ``4 | ( 255 << 8 )`` will consider 4 nearest neighbours and fill the mask with a value of 255. The following additional options occupy higher bits and therefore may be further combined with the connectivity and mask fill values using bit-wise or (``|``):
* **FLOODFILL_FIXED_RANGE** If set, the difference between the current pixel and seed pixel is considered. Otherwise, the difference between neighbor pixels is considered (that is, the range is floating).
* **FLOODFILL_MASK_ONLY** If set, the function does not change the image ( ``newVal`` is ignored), but fills the mask. The flag can be used for the second variant only.
* **FLOODFILL_MASK_ONLY** If set, the function does not change the image ( ``newVal`` is ignored), and only fills the mask with the value specified in bits 8-16 of ``flags`` as described above. This option only make sense in function variants that have the ``mask`` parameter.
The functions ``floodFill`` fill a connected component starting from the seed point with the specified color. The connectivity is determined by the color/brightness closeness of the neighbor pixels. The pixel at
:math:`(x,y)` is considered to belong to the repainted domain if:

@ -133,7 +133,7 @@ Finds contours in a binary image.
.. ocv:pyoldfunction:: cv.FindContours(image, storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0, 0)) -> contours
:param image: Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero pixels remain 0's, so the image is treated as ``binary`` . You can use :ocv:func:`compare` , :ocv:func:`inRange` , :ocv:func:`threshold` , :ocv:func:`adaptiveThreshold` , :ocv:func:`Canny` , and others to create a binary image out of a grayscale or color one. The function modifies the ``image`` while extracting the contours.
:param image: Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero pixels remain 0's, so the image is treated as ``binary`` . You can use :ocv:func:`compare` , :ocv:func:`inRange` , :ocv:func:`threshold` , :ocv:func:`adaptiveThreshold` , :ocv:func:`Canny` , and others to create a binary image out of a grayscale or color one. The function modifies the ``image`` while extracting the contours. If mode equals to ``CV_RETR_CCOMP`` or ``CV_RETR_FLOODFILL``, the input can also be a 32-bit integer image of labels (``CV_32SC1``).
:param contours: Detected contours. Each contour is stored as a vector of points.

@ -453,8 +453,11 @@ void FilterEngine::apply(const Mat& src, Mat& dst,
dstOfs.y + srcRoi.height <= dst.rows );
int y = start(src, srcRoi, isolated);
proceed( src.data + y*src.step, (int)src.step, endY - startY,
dst.data + dstOfs.y*dst.step + dstOfs.x*dst.elemSize(), (int)dst.step );
proceed( src.data + y*src.step
+ srcRoi.x*src.elemSize(),
(int)src.step, endY - startY,
dst.data + dstOfs.y*dst.step +
dstOfs.x*dst.elemSize(), (int)dst.step );
}
}

@ -837,7 +837,7 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
if( borderType != BORDER_CONSTANT )
if( borderType != BORDER_CONSTANT && (borderType & BORDER_ISOLATED) != 0 )
{
if( src.rows == 1 )
ksize.height = 1;

@ -333,12 +333,6 @@ void CvCalibFilter::Stop( bool calibrate )
points[0],points[1],
buffer,
&stereo);
for( i = 0; i < 9; i++ )
{
stereo.fundMatr[i] = stereo.fundMatr[i];
}
}
}

@ -577,54 +577,48 @@ void BackgroundSubtractorMOG2::operator()(InputArray _image, OutputArray _fgmask
void BackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage) const
{
int nchannels = CV_MAT_CN(frameType);
CV_Assert( nchannels == 3 );
Mat meanBackground(frameSize, CV_8UC3, Scalar::all(0));
CV_Assert(nchannels == 1 || nchannels == 3);
Mat meanBackground(frameSize, CV_MAKETYPE(CV_8U, nchannels), Scalar::all(0));
int firstGaussianIdx = 0;
const GMM* gmm = (GMM*)bgmodel.data;
const Vec3f* mean = reinterpret_cast<const Vec3f*>(gmm + frameSize.width*frameSize.height*nmixtures);
const float* mean = reinterpret_cast<const float*>(gmm + frameSize.width*frameSize.height*nmixtures);
std::vector<float> meanVal(nchannels, 0.f);
for(int row=0; row<meanBackground.rows; row++)
{
for(int col=0; col<meanBackground.cols; col++)
{
int nmodes = bgmodelUsedModes.at<uchar>(row, col);
Vec3f meanVal;
float totalWeight = 0.f;
for(int gaussianIdx = firstGaussianIdx; gaussianIdx < firstGaussianIdx + nmodes; gaussianIdx++)
{
GMM gaussian = gmm[gaussianIdx];
meanVal += gaussian.weight * mean[gaussianIdx];
size_t meanPosition = gaussianIdx*nchannels;
for(int chn = 0; chn < nchannels; chn++)
{
meanVal[chn] += gaussian.weight * mean[meanPosition + chn];
}
totalWeight += gaussian.weight;
if(totalWeight > backgroundRatio)
break;
}
meanVal *= (1.f / totalWeight);
meanBackground.at<Vec3b>(row, col) = Vec3b(meanVal);
float invWeight = 1.f/totalWeight;
switch(nchannels)
{
case 1:
meanBackground.at<uchar>(row, col) = (uchar)(meanVal[0] * invWeight);
meanVal[0] = 0.f;
break;
case 3:
Vec3f& meanVec = *reinterpret_cast<Vec3f*>(&meanVal[0]);
meanBackground.at<Vec3b>(row, col) = Vec3b(meanVec * invWeight);
meanVec = 0.f;
break;
}
firstGaussianIdx += nmixtures;
}
}
switch(CV_MAT_CN(frameType))
{
case 1:
{
vector<Mat> channels;
split(meanBackground, channels);
channels[0].copyTo(backgroundImage);
break;
}
case 3:
{
meanBackground.copyTo(backgroundImage);
break;
}
default:
CV_Error(CV_StsUnsupportedFormat, "");
}
meanBackground.copyTo(backgroundImage);
}
}

@ -33,7 +33,7 @@ int main( int /*argc*/, char** /*argv*/ )
{
int k, clusterCount = rng.uniform(2, MAX_CLUSTERS+1);
int i, sampleCount = rng.uniform(1, 1001);
Mat points(sampleCount, 2, CV_32F), labels;
Mat points(sampleCount, 1, CV_32FC2), labels;
clusterCount = MIN(clusterCount, sampleCount);
Mat centers;

Loading…
Cancel
Save