# What's the middle dimension for the result of findCountours?

**URL:** <https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810>\
**Category:** Python\
**Tags:** core\
**Created:** [April 14, 2023, 4:58pm UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810 "2023-04-14T16:58:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stuart\_Reynolds](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/stuart_reynolds/32/4079_2.png) [@Stuart\_Reynolds](https://forum.opencv.org/u/Stuart_Reynolds)\
**Post date:** [April 14, 2023, 4:58pm UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810/1 "2023-04-14T16:58:54Z")

</div>

findCountours returns a list of arrays.  
What does the middle dimension for the contours represent?

`contours[0].shape -> (136, 1, 2)`

---

<div class="post-metadata">

**Author:** ![laurent.berger](https://avatars.discourse-cdn.com/v4/letter/l/ec9cab/32.png) [@laurent.berger](https://forum.opencv.org/u/laurent.berger)\
**Post date:** [April 14, 2023, 6:35pm UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810/2 "2023-04-14T18:35:38Z")

</div>

It’s an array of 136 points and a point is an array of 1 row and 2 columns

---

<div class="post-metadata">

**Author:** ![Stuart\_Reynolds](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/stuart_reynolds/32/4079_2.png) [@Stuart\_Reynolds](https://forum.opencv.org/u/Stuart_Reynolds)\
**Post date:** [April 14, 2023, 6:43pm UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810/3 "2023-04-14T18:43:06Z")

</div>

Yes. We have: (point, ??, xy)  
Why arity 3 indexes when 2, (point, xy), is sufficient?

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [April 14, 2023, 6:51pm UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810/4 "2023-04-14T18:51:33Z")

</div>

Let me explain. It all begins in C++.

`cv::Mat` is not quite a matrix. it’s an image container. it has a number of rows and columns, but also a number of channels.

each entry of the matrix can be a single number, but it can also be a “vector”, or `cv::Scalar` (really a vector). for images, a cv::Mat has 3 channels or something like that.

This “Scalar” thing is convenient because now you can index a single element of the matrix and you get a Scalar/vector. you don’t need to “select the row”, as you would otherwise.

the result of `findContours` is a list of contours. each contour is a Mat, containing the points. the points are put into the Mat as a “column vector” of **points**.

that means the Mat is **Nx1** , and 2-channel (`CV_32SC2` perhaps), so it can hold (x,y) Points.

the mapping from `cv::Mat` to _numpy array_ always maps to `(nrows, ncols, nchannels)` or `(nrows, ncols)` if there’s just one channel (grayscale image or “actual” matrix data).

that’s why you get (N, 1, 2).

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [April 15, 2023, 9:57am UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810/5 "2023-04-15T09:57:19Z")

</div>

just for the record, starting with 4.6.0, python bindings changed, the additional dimension (wrapping `std::vector<T>`) was removed, so we have:

- pre 4.6  
`std::vector<cv::Point> -> [N, 1, 2]`
- post 4.6  
`std::vector<cv::Point> -> [N, 2]`

(just saying, not all of the python samples might be up to date here !)

---

<div class="post-metadata">

**Author:** ![laurent.berger](https://avatars.discourse-cdn.com/v4/letter/l/ec9cab/32.png) [@laurent.berger](https://forum.opencv.org/u/laurent.berger)\
**Post date:** [April 15, 2023, 11:16am UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810/6 "2023-04-15T11:16:25Z")

</div>

> [@berak](#):
>
> python bindings

```auto
import cv2 as cv
import numpy as np
img = np.zeros((256, 256), np.uint8)
cv.rectangle(img,(160, 100, 50, 20), 255, -1)
img = cv.circle(img, (50,50), 20, 255, -1)
ctr, _ =cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)

```

then ctr is a list

```auto
>>> len(ctr)
2

```

and

```auto
>>> ctr[0].shape
(136, 1, 2)

```

and

```auto
>>> print(cv.getBuildInformation())

General configuration for OpenCV 4.7.0-dev =====================================
  Version control: 4.7.0-185-g61d255887c

  Extra modules:
    Location (extra): C:/lib/opencv_contrib/modules
    Version control (extra): 4.7.0-31-g853144ef

```

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [April 15, 2023, 11:40am UTC](https://forum.opencv.org/t/whats-the-middle-dimension-for-the-result-of-findcountours/12810/7 "2023-04-15T11:40:46Z")

</div>

that’s because `std::vector<cv::Mat>` are returned, _not_ vectors of cv::Points. I don’t believe that `std::vector<cv::Point>` ever mapped to an additional dimension, so that is irrelevant to the situation.
