0

I have been trying to find the outline (external contour) of a whiteboard marker in an Image. I have tried using openCv for this (seems to be the least complicated). I have gray-scaled and filtered the Image but I still can't get to a good enough results. The Images I am working on are very good (e.g don't have any other object in them) and I am quite sure this is possible (without the use of heavy DL algorithms).

This is what I am getting:

enter image description here

This is (roughly) what I am trying to get (this was done using Photoshop's magic wand):

enter image description here

I have tried different algorithms but none seem to work (The result above just uses cv2.findContours with cv2.RETR_TREE and cv2.CHAIN_APPROX_SIMPLE). I have found many people asking some very similar questions but the answers given to them did not work for me.

(for example: Process image to find external contour or https://answers.opencv.org/question/182345/how-do-i-draw-only-external-contour/)

Here is the original image:

enter image description here

In any case, thanks for your help!

  • If you read though the Findcontous in open CV there different mode can be sent to that function. To find external one try we need to send cv2.RETR_EXTERNAL inplace of cv2.RETR_TREE – Sreevathsabr Apr 09 '20 at 20:03
  • Please post your code so others can correct it. – fmw42 Apr 09 '20 at 20:29
  • @ashtav I tried using RETER_EXTERNAL but the outline was composed out of several different contours. Thanks for you answer! – Itamar Safriel Apr 09 '20 at 21:05
  • @fmw42 I posted some code that worked down below. Thanks! – Itamar Safriel Apr 09 '20 at 21:05
  • Take a look at this [question](https://stackoverflow.com/questions/47777585/detecting-outer-most-edge-of-image-and-plotting-based-on-it) I believe this is what you are looking for. – sinshev Apr 09 '20 at 20:02

1 Answers1

0

So using the link Sergey provided and using a threshold instead of grey scale I get much better results. This is the code:

import cv2 # Import OpenCV
import numpy as np # Import NumPy
from matplotlib import pyplot as plt

image = cv2.imread("./image.jpg")

height, width = image.shape[0], image.shape[1]

white_padding = np.zeros((50, width, 3))
white_padding[:, :] = [255, 255, 255]
image = np.row_stack((white_padding, image))

_, mask = cv2.threshold(image, 220, 255, cv2.THRESH_BINARY_INV)


kernel = np.ones((30, 30), np.uint8)
closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)

closing_uint8 = np.uint8(closing)


edges = cv2.Canny(closing_uint8, 100, 200)

plt.imshow(edges)
plt.show() 

The problem with this is that the size of the Kernel needs to be changed for different images, for example, this image:

enter image description here

outputs this: enter image description here

Any ideas on how to face this problem? Thanks for your help!

  • I do not understand what you mean by the colors are wrong. When you use Mathplotpy to show and image, it gets a colored lookup table applied. If you want to see the actual colors, use cv2.imshow(). – fmw42 Apr 09 '20 at 21:13