2017-11-20 22:49:12 8 Comments

I am trying to triangulate points from a projector and a camera using Structured Light in OpenCV Python. In this process I have a list of tuples that match one to one between the camera and the projector. I am passing this to cv2.undistortedPoints() as below:

`camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d)`

However, python is throwing the following error and I am unable to understand what the error means.

```
camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d)
cv2.error: /home/base/opencv_build/opencv/modules/imgproc/src/undistort.cpp:312: error: (-215) CV_IS_MAT(_src) && CV_IS_MAT(_dst) && (_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2) in function cvUndistortPoints
```

Any help is greatly appreciated.

Thanks.

### Related Questions

#### Sponsored Content

#### 32 Answered Questions

#### 2 Answered Questions

#### 1 Answered Questions

#### 7 Answered Questions

### [SOLVED] Understanding Python super() with __init__() methods

**2009-02-23 00:30:08****Mizipzor****1535314**View**2308**Score**7**Answer- Tags: python class oop inheritance super

#### 1 Answered Questions

#### 1 Answered Questions

### [SOLVED] OpenCV Error: Assertion failed in undistort.cpp at line 293

**2017-05-18 08:22:11****djkp****1480**View**4**Score**1**Answer- Tags: python opencv numpy opencv3.0 opencv-solvepnp

#### 1 Answered Questions

### Weird error thrown by cv2.fitLine() method

**2016-12-22 15:54:13****zeo****938**View**2**Score**1**Answer- Tags: python python-3.x opencv numpy computer-vision

#### 1 Answered Questions

### [SOLVED] Why i have this issue with cv2.findContours function?

**2016-04-20 17:35:53****moli****686**View**-1**Score**1**Answer- Tags: python python-2.7 opencv

#### 1 Answered Questions

### [SOLVED] opencv, python and RaspberryPi

**2015-07-24 01:44:21****prinks****670**View**1**Score**1**Answer- Tags: python opencv raspberry-pi

## 2 comments

## @B.Blue 2019-01-07 03:30:27

I also reach this problems, and I take some time to research an finally understand.

In the open system, distort operation is before camera matrix, so the process order is: image_distorted ->camera_matrix -> un-distort function->camera_matrix->back to image_undistorted.

So you need a small fix to and camera_K again.

camera_normalizedPoints = cv2.undistortPoints(camera_points, camera_K, camera_d, cv2.Mat.sye(3,3), camera_K)

Forumla: https://i.stack.imgur.com/nmR5P.jpg

## @alkasm 2017-11-21 00:16:49

The documentation is not always explicit about the input shape in Python unfortunately, and

`undistortPoints()`

doesn't even have Python documentation yet.The input points need to be an array with the shape

`(n_points, 1, n_dimensions)`

. So if you have 2D coordinates, they should be in the shape`(n_points, 1, 2)`

. Or for 3D coordinates they should be in the shape`(n_points, 1, 3)`

. This is true formostOpenCV functions. AFAIK, this format will work forallOpenCV functions, while some few OpenCV functions will also accept points in the shape`(n_points, n_dimensions)`

. I find it best to just keep everything consistent and in the format`(n_points, 1, n_dimensions)`

.To be clear this means an array of four 32-bit float 2D points would look like:

If you have an array that has the shape

`(n_points, n_dimensions)`

you can expand it with`np.newaxis`

:or with

`np.expand_dims()`

:or with various orderings of

`np.transpose()`

depending on the order of your dimensions. For e.g. if your shape is`(1, n_points, n_dimensions)`

then you want to swap axis 0 with axis 1 to get`(n_points, 1, n_dimensions)`

, so`points = np.transpose(points, (1, 0, 2))`

would change the axes to put axis 1 first, then axis 0, then axis 2, so the new shape would be correct.If you think this is an odd format for points, it is if you only consider a list of points, but reasonable if you think about points as coordinates of an image. If you have an image, then the coordinates of each point in the image is defined by an

`(x, y)`

pair, like:Here it makes sense to put each coordinate into a separate channel of a two-channel array, so that you get one 2D array of x-coordinates, and one 2D array of y-coordinates, like:

Channel 0 (x-coordinates):

Channel 1 (y-coordinates):

So that's the reason for having each coordinate on a separate channel.

Some other OpenCV functions which require this format include

`cv2.transform()`

and`cv2.perspectiveTransform()`

, which I've answered identical questions about before, here and here respectively.