# Draw and fill a polygon from 2 lines using openCV

**URL:** <https://forum.opencv.org/t/draw-and-fill-a-polygon-from-2-lines-using-opencv/1056>\
**Category:** Python\
**Created:** [January 22, 2021, 7:22pm UTC](https://forum.opencv.org/t/draw-and-fill-a-polygon-from-2-lines-using-opencv/1056 "2021-01-22T19:22:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Guilherme\_Augusto](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/guilherme_augusto/32/700_2.png) [@Guilherme\_Augusto](https://forum.opencv.org/u/Guilherme_Augusto)\
**Post date:** [January 22, 2021, 7:22pm UTC](https://forum.opencv.org/t/draw-and-fill-a-polygon-from-2-lines-using-opencv/1056/1 "2021-01-22T19:22:29Z")

</div>

I have a picture with 2 curves and multiple small lines which can be interpreted as noise.

 ![](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/1X/9e98825e6b07d90cb88ab128339dcf929dc209db.png)

I need to create a polygon with these curves and fill them with white like the output below :

https://i.stack.imgur.com/SRt5Y.png

I tried the following code :

```auto
import cv2
from google.colab.patches import cv2_imshow
from google.colab import drive
import numpy as np

filePath = '/gdrive/My Drive/teste17.png'
image = cv2.imread(filePath)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 

cv2_imshow(image)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

coords = np.column_stack(np.where(thresh > 0))

c2=np.stack((coords[:,1], coords[:,0]), axis=-1)

cv2.fillPoly(image, [c2], (255, 0, 0))

cv2_imshow(image)

```

But the output was a bit different from what I wanted :

[https://i.stack.imgur.com/DovEt.png](https://i.stack.imgur.com/DovEt.png)

Is there a better approach using openCV ? Any suggestions is appreciated.

---

<div class="post-metadata">

**Author:** ![furas](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/furas/32/706_2.png) [@furas](https://forum.opencv.org/u/furas)\
**Post date:** [January 23, 2021, 7:12am UTC](https://forum.opencv.org/t/draw-and-fill-a-polygon-from-2-lines-using-opencv/1056/2 "2021-01-23T07:12:44Z")

</div>

I would try to use `findContours()` to find all white objects, next use `contourArea()` to get two objects with the biggest areas, and finally I would use only these objects to draw blue polygon.

Doc: [Contour: Getting Started](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html), [Contour Features](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html)

* * *

At this moment I can get only

 ![result](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/1X/2dfe7bc29b7704e860780b3d64b0e771e457ec37.png)

with this code (I don’t use `Google Colab`)

```auto
import cv2
#from google.colab.patches import cv2_imshow
#from google.colab import drive
import numpy as np

# emulate `cv2_imshow` without using `google.colab
cv2_imshow = lambda img:cv2.imshow('image', img) or cv2.waitKey(0)

#filePath = '/gdrive/My Drive/teste17.png'
filePath = 'image.png'

image = cv2.imread(filePath)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 
#cv2_imshow(image)

thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

# ---- 

# find all contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 
print('len(contours):', len(contours))
#print(contours, hierarchy)

# calculate areas for all contours 
# and keep on list as `(area, contour)`
contour_area = []
for c in contours:
    print('area:', cv2.contourArea(c))
    contour_area.append((cv2.contourArea(c), c))

print('--- contour_area ---')
for item in contour_area:
    print('contour_area:', item[0])
    
# sort list with `(area, contour)` using only `area`    
contour_area = sorted(contour_area, key=lambda x:x[0], reverse=True)

print('--- contour_area - sorted ---')
for item in contour_area:
    print('contour_area:', item[0])
    
# get two the biggest contours    
print('--- two the biggest contours ---')    
print('p0:', contour_area[0][0])
print('p1:', contour_area[1][0])

# draw them
coords = np.vstack([contour_area[0][1], contour_area[1][1]])
cv2.fillPoly(image, [coords], (255, 0, 0))

cv2_imshow(image)

```

---

<div class="post-metadata">

**Author:** ![Guilherme\_Augusto](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/guilherme_augusto/32/700_2.png) [@Guilherme\_Augusto](https://forum.opencv.org/u/Guilherme_Augusto)\
**Post date:** [January 26, 2021, 9:04pm UTC](https://forum.opencv.org/t/draw-and-fill-a-polygon-from-2-lines-using-opencv/1056/3 "2021-01-26T21:04:04Z")

</div>

Thank you !

I actually created a black image (image2) and filled it with the blue contours calculated in white. Then I found all white pixels in the picture and used these coordinates to apply cv2.fillPoly on the original image.

Here is the code :

```auto
import cv2

from google.colab.patches import cv2_imshow

from google.colab import drive

import numpy as np

filePath = '/gdrive/My Drive/teste17.png'

image = cv2.imread(filePath)

height,width,channel = image.shape

print(channel)

#image = cv2.rotate(image, cv2.cv2.ROTATE_90_CLOCKWISE)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 

cv2_imshow(image)

thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 

contour_area = []

for c in contours:

    print('area:', cv2.contourArea(c))

    contour_area.append((cv2.contourArea(c), c))

print('--- contour_area ---')

for item in contour_area:

    print('contour_area:', item[0])

    

# sort list with `(area, contour)` using only `area`    

contour_area = sorted(contour_area, key=lambda x:x[0], reverse=True)

print('--- contour_area - sorted ---')

for item in contour_area:

    print('contour_area:', item[0])

    

# get two the biggest contours    

print('--- two the biggest contours ---')    

print('p0:', contour_area[0][0])

print('p1:', contour_area[1][0])

image2 = np.zeros((height, width, 3), dtype = "uint8")

# draw them

coords1 = np.vstack([contour_area[0][1], contour_area[1][1]])

cv2.fillPoly(image2, [coords1], (255, 255, 255))

gray = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) 

thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

coords = np.column_stack(np.where(thresh1 > 0))

c2=np.stack((coords[:,1], coords[:,0]), axis=-1)

cv2.fillPoly(image, [c2], (255, 255, 255))

cv2_imshow(image)

```

And I got the right output :

 ![output](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/1X/04a40a2d744936dd3bc7281f1da8e3bd0094f8d4.png)

Once again, thank you for your help !
