]> rtime.felk.cvut.cz Git - opencv.git/commitdiff
#150 ReshapeMatND: test, implementaton, doc
authorjamesb <jamesb@73c94f0f-984f-4a5f-82bc-2d8db8d8ee08>
Tue, 30 Mar 2010 22:05:30 +0000 (22:05 +0000)
committerjamesb <jamesb@73c94f0f-984f-4a5f-82bc-2d8db8d8ee08>
Tue, 30 Mar 2010 22:05:30 +0000 (22:05 +0000)
git-svn-id: https://code.ros.org/svn/opencv/trunk@2950 73c94f0f-984f-4a5f-82bc-2d8db8d8ee08

opencv/doc/cxcore_array_operations.tex
opencv/doc/latex2sphinx/go
opencv/interfaces/python/api
opencv/interfaces/python/cv.cpp
opencv/tests/python/test.py

index c8c34072e9bca430fe90dbd0fc86540141d5ed9c..4a36bf55f0e030dac45bf1b8019e7b2e634c641d 100644 (file)
@@ -2905,13 +2905,15 @@ Changes the shape of a multi-dimensional array without copying the data.
 \cvarg{newSizes}{Array of new dimension sizes. Only $\texttt{newDims}-1$ values are used, because the total number of elements must remain the same.
 Thus, if $\texttt{newDims} = 1$, \texttt{newSizes} array is not used.}
 \else
+\cvarg{newCn}{New number of channels. $\texttt{newCn} = 0$ means that the number of channels remains unchanged.}
 \cvarg{newDims}{List of new dimensions.}
 \fi
 \end{description}
 
-The function is an advanced version of \cvCPyCross{Reshape} that can work with multi-dimensional arrays as well (though it can work with ordinary images and matrices) and change the number of dimensions.
 
 \ifC
+The function is an advanced version of \cvCPyCross{Reshape} that can work with multi-dimensional arrays as well (though it can work with ordinary images and matrices) and change the number of dimensions.
+
 Below are the two samples from the \cvCPyCross{Reshape} description rewritten using \cvCPyCross{ReshapeMatND}:
 
 \begin{lstlisting}
@@ -2931,6 +2933,24 @@ row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0);
 \end{lstlisting}
 \fi
 
+\ifPy
+Returns a new \cross{CvMatND} that shares the same data as \texttt{arr}
+but has different dimensions or number of channels.  The only requirement
+is that the total length of the data is unchanged.
+
+\begin{lstlisting}
+>>> import cv
+>>> mat = cv.CreateMatND([24], cv.CV_32FC1)
+>>> print cv.GetDims(cv.ReshapeMatND(mat, 0, [8, 3]))
+(8, 3)
+>>> m2 = cv.ReshapeMatND(mat, 4, [3, 2])
+>>> print cv.GetDims(m2)
+(3, 2)
+>>> print m2.channels
+4
+\end{lstlisting}
+\fi
+
 \ifC
 \cvfunc{cvRound, cvFloor, cvCeil}\label{cvRound}
 
index b991b07d2bd00f0b02d5b2ce4b68ae75ee35c869..c0ed40dec0d1f8919aba7913da513c410b5d9cb1 100644 (file)
@@ -1,7 +1,6 @@
 #!/bin/bash
 
 LANGUAGES="c cpp py"
-LANGUAGES="py"
 
 mkdir -p $LANGUAGES
 tput clear
index 69502d387efc85b87f54f87732da3b479765696b..b0ebc3712f0f1ae135be9ab5cb242b48fda3e27e 100644 (file)
@@ -1765,7 +1765,7 @@ InitLineIterator line_iterator /doconly
   CvArr image
   CvPoint pt1
   CvPoint pt2
-  int line_iterator /O
+  iter line_iterator /O
   int connectivity 8
   int left_to_right 0
 LoadImageM /doconly
@@ -1777,7 +1777,7 @@ LoadImage /doconly
 ReshapeMatND /doconly
   CvMat arr
   int newCn
-  int newDims
+  ints newDims
 Reshape /doconly
   CvArr arr
   int newCn
index 774d210e71e6c6da88cbf1fb9551124b691d27be..5728d1ebd8d16bbedbfe1cc222b6794053d1da85 100644 (file)
@@ -122,6 +122,7 @@ static int convert_to_CvMatND(PyObject *o, CvMatND **dst, const char *name = "no
 static PyObject *what_data(PyObject *o);
 static PyObject *FROM_CvMat(CvMat *r);
 static PyObject *FROM_ROCvMatPTR(ROCvMat *r);
+static PyObject *shareDataND(PyObject *donor, CvMatND *pdonor, CvMatND *precipient);
 
 #define FROM_double(r)  PyFloat_FromDouble(r)
 #define FROM_float(r)  PyFloat_FromDouble(r)
@@ -337,6 +338,7 @@ static void iplimage_setorigin(iplimage_t *cva, PyObject *v)
 
 static PyGetSetDef iplimage_getseters[] = {
   {(char*)"nChannels", (getter)iplimage_getnChannels, (setter)NULL, (char*)"nChannels", NULL},
+  {(char*)"channels", (getter)iplimage_getnChannels, (setter)NULL, (char*)"nChannels", NULL},
   {(char*)"width", (getter)iplimage_getwidth, (setter)NULL, (char*)"width", NULL},
   {(char*)"height", (getter)iplimage_getheight, (setter)NULL, (char*)"height", NULL},
   {(char*)"depth", (getter)iplimage_getdepth, (setter)NULL, (char*)"depth", NULL},
@@ -473,6 +475,11 @@ static PyObject *cvmat_getcols(cvmat_t *cva)
   return PyInt_FromLong(cva->a->cols);
 }
 
+static PyObject *cvmat_getchannels(cvmat_t *cva)
+{
+  return PyInt_FromLong(CV_MAT_CN(cva->a->type));
+}
+
 #if PYTHON_USE_NUMPY
 #include "numpy/ndarrayobject.h"
 
@@ -627,6 +634,7 @@ static PyGetSetDef cvmat_getseters[] = {
   {(char*)"step",   (getter)cvmat_getstep, (setter)NULL, (char*)"step",   NULL},
   {(char*)"rows",   (getter)cvmat_getrows, (setter)NULL, (char*)"rows",   NULL},
   {(char*)"cols",   (getter)cvmat_getcols, (setter)NULL, (char*)"cols",   NULL},
+  {(char*)"channels",(getter)cvmat_getchannels, (setter)NULL, (char*)"channels",   NULL},
   {(char*)"width",  (getter)cvmat_getcols, (setter)NULL, (char*)"width",  NULL},
   {(char*)"height", (getter)cvmat_getrows, (setter)NULL, (char*)"height", NULL},
 #if PYTHON_USE_NUMPY
@@ -778,10 +786,16 @@ static struct PyMethodDef cvmatnd_methods[] =
   {NULL,          NULL}
 };
 
+static PyObject *cvmatnd_getchannels(cvmatnd_t *cva)
+{
+  return PyInt_FromLong(CV_MAT_CN(cva->a->type));
+}
+
 static PyGetSetDef cvmatnd_getseters[] = {
 #if PYTHON_USE_NUMPY
   {(char*)"__array_struct__", (getter)cvmatnd_array_struct, (setter)NULL, (char*)"__array_struct__", NULL},
 #endif
+  {(char*)"channels",(getter)cvmatnd_getchannels, (setter)NULL, (char*)"channels",   NULL},
   {NULL}  /* Sentinel */
 };
 
@@ -3204,7 +3218,7 @@ static PyObject *pycvReshapeMatND(PyObject *self, PyObject *args)
   int new_cn = 0;
   PyObject *new_dims = NULL;
 
-  if (!PyArg_ParseTuple(args, "O|iO", &o, &new_cn, &new_dims))
+  if (!PyArg_ParseTuple(args, "OiO", &o, &new_cn, &new_dims))
     return NULL;
 
   CvMatND *cva;
@@ -3216,49 +3230,25 @@ static PyObject *pycvReshapeMatND(PyObject *self, PyObject *args)
       return NULL;
   }
 
-#if 0
-  if ((dims.count + 1) <= 2) {
-    CvMat *m = cvCreateMatHeader(100, 100, 1); // these args do not matter, because overwritten
-    if (new_dims != NULL) {
-      printf("newcn=%d newdims=%d newSizes=%p\n", new_cn, dims.count + 1, dims.i);
-      ERRWRAP(cvReshapeND(cva, m, new_cn, dims.count + 1, dims.i));
-    } else {
-      ERRWRAP(cvReshapeND(cva, m, new_cn, 0, NULL));
-    }
+  if (new_cn == 0)
+    new_cn = CV_MAT_CN(cvGetElemType(cva));
 
-    cvmat_t *om = PyObject_NEW(cvmat_t, &cvmat_Type);
-    om->a = m;
-    om->data = what_data(o);
-    Py_INCREF(om->data);
-    om->offset = 0;
-    return (PyObject*)om;
-  } else {
-    int dummy[1] = { 1 };
-    CvMatND *m = cvCreateMatNDHeader(1, dummy, 1); // these args do not matter, because overwritten
-    if (new_dims != NULL) {
-      printf("newcn=%d newdims=%d newSizes=%p\n", new_cn, dims.count + 1, dims.i);
-      ERRWRAP(cvReshapeND(cva, m, new_cn, dims.count + 1, dims.i));
-    } else {
-      ERRWRAP(cvReshapeND(cva, m, new_cn, 0, NULL));
-    }
+  int i;
+  int count = CV_MAT_CN(cvGetElemType(cva));
+  for (i = 0; i < cva->dims; i++)
+    count *= cva->dim[i].size;
 
-    cvmatnd_t *om = PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
-    om->a = m;
-    om->data = what_data(o);
-    Py_INCREF(om->data);
-    om->offset = 0;
-    return (PyObject*)om;
-  }
-#else
-  {
-    int size[] = { 2, 2, 2 };
-    CvMatND* mat = cvCreateMatND(3, size, CV_32F);
-    CvMat row_header;
-    CvArr *row;
-    row = cvReshapeND(mat, &row_header, 0, 1, 0);
+  int newcount = new_cn;
+  for (i = 0; i < dims.count; i++)
+    newcount *= dims.i[i];
+
+  if (count != newcount) {
+    PyErr_SetString(PyExc_TypeError, "Total number of elements must be unchanged");
+    return NULL;
   }
-  Py_RETURN_NONE;
-#endif
+
+  CvMatND *pn = cvCreateMatNDHeader(dims.count, dims.i, CV_MAKETYPE(CV_MAT_TYPE(cva->type), new_cn));
+  return shareDataND(o, cva, pn);
 }
 
 static void OnMouse(int event, int x, int y, int flags, void* param)
@@ -3658,6 +3648,19 @@ static PyObject *shareData(PyObject *donor, CvArr *pdonor, CvMat *precipient)
   return recipient;
 }
 
+static PyObject *shareDataND(PyObject *donor, CvMatND *pdonor, CvMatND *precipient)
+{
+  PyObject *recipient = (PyObject*)PyObject_NEW(cvmatnd_t, &cvmatnd_Type);
+  ((cvmatnd_t*)recipient)->a = precipient;
+  ((cvmatnd_t*)recipient)->offset = 0;
+
+  PyObject *arr_data;
+  arr_data = ((cvmatnd_t*)donor)->data;
+  ((cvmatnd_t*)recipient)->data = arr_data;
+  Py_INCREF(arr_data);
+  return recipient;
+}
+
 static PyObject *pycvGetHuMoments(PyObject *self, PyObject *args)
 {
   CvMoments* moments;
index 1e3c2d5015c60bf1671e9e04ef31ee092ea40e46..d87c6e1afb2fd13247c7777a287a93c3df4a12c4 100644 (file)
@@ -680,10 +680,12 @@ class FunctionTests(OpenCVTests):
         self.assert_((nc * nr * nd) == elems)
 
         # Now test ReshapeMatND
-        mat = cv.CreateMatND([24], cv.CV_32F)
+        mat = cv.CreateMatND([24], cv.CV_32FC1)
         cv.Set(mat, 1.0)
-        self.assertEqual(cv.GetDims(cv.ReshapeMatND(mat, 0, [])), (24, 1))
-        self.assertEqual(cv.GetDims(cv.ReshapeMatND(mat, 0, [1])), (6, 4))
+        self.assertEqual(cv.GetDims(cv.ReshapeMatND(mat, 0, [24, 1])), (24, 1))
+        self.assertEqual(cv.GetDims(cv.ReshapeMatND(mat, 0, [6, 4])), (6, 4))
+        self.assertEqual(cv.GetDims(cv.ReshapeMatND(mat, 24, [1])), (1,))
+        self.assertRaises(TypeError, lambda: cv.ReshapeMatND(mat, 12, [1]))
 
     def test_Save(self):
         for o in [ cv.CreateImage((128,128), cv.IPL_DEPTH_8U, 1), cv.CreateMat(16, 16, cv.CV_32FC1) ]:
@@ -813,6 +815,18 @@ class AreaTests(OpenCVTests):
             cv.AddS(ones, 7, r)
             self.assert_(numpy.alltrue(r == (8 * ones)))
 
+            # create arrays, use them in OpenCV and replace the the array
+            # looking for leaks
+            def randdim():
+                return [random.randrange(1,6) for i in range(random.randrange(1, 6))]
+            as = [numpy.ones(randdim()).astype(numpy.uint8) for i in range(10)]
+            cs = [cv.fromarray(a, True) for a in as]
+            for i in range(1000):
+                as[random.randrange(10)] = numpy.ones(randdim()).astype(numpy.uint8)
+                cs[random.randrange(10)] = cv.fromarray(as[random.randrange(10)], True)
+                for j in range(10):
+                    self.assert_(all([c == chr(1) for c in cs[j].tostring()]))
+
         else:
             print "SKIPPING test_numpy - numpy support not built"