How to find contours in image using evision and nx?

You can use the same function in evision, Evision.contourArea/1.

Is it possible to get the edges of box?

It is possible. And it’s still the same function, Evision.approxPolyDP/3.

1 Like

I have tried various methods of finding contours of an image in elixir and i am still stuck at the same point. This is the error it shows when I tried to use findContours function in Evision Library. Can someone please help me out.

The error message already tells you your issue. The first parameter cannot be a path – you’re passing a path.

You likely want OpenCV.findContours(im, … not OpenCV.findContours(image, …

Segmentation fault (core dumped)

0.1.7 is outdated, please use the latest one.

Other than that, Evision.findContours/3 expects the first argument, im (in your case), to be a 1-channel image. That means the coloured 3-channel image must be processed to a binary(1-channel) image. That’s one reason why you got a segmentation fault. (the other reason is that 0.1.7 is outdated and you won’t get a segmentation fault in the latest version even if you passed in an unexpected input.)

For your reference, Evision.threshold/{4,5} is a frequently used technique to get you a binary image. And of course, the value of the second parameter thresh (in Evision.threshold) could vary a lot based on your source image like its brightness and contrast.

Also, please read the inline docs. Pulling up the inline docs and presenting them in a friendly way is a built-in feature of IEx. It only requires one to type h ModuleName.FunctionName. For example

iex> h Evision.findContours

                     def findContours(image, mode, method)

  @spec findContours(Evision.Mat.maybe_mat_in(), integer(), integer()) ::
          {[Evision.Mat.t()], Evision.Mat.t()} | {:error, String.t()}

Finds contours in a binary image.

##### Positional Arguments

  • **image**: `Evision.Mat`.
    Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's.
    Zero pixels remain 0's, so the image is treated as binary . You can use
    #compare, #inRange, #threshold , #adaptiveThreshold, #Canny, and others to
    create a binary image out of a grayscale or color one. If mode equals to
    #RETR_CCOMP or #RETR_FLOODFILL, the input can also be a 32-bit integer
    image of labels (CV_32SC1).

  • **mode**: `int`.
    Contour retrieval mode, see #RetrievalModes

  • **method**: `int`.
    Contour approximation method, see #ContourApproximationModes

##### Keyword Arguments

In latest version.0.1.12
Ehen i use imshow throwing some error
But when imshow in 0.1.0 its working fine!?

You should provide the error stack trace…

As of 0.1.12, the precompiled binaries for Linux are using GTK2 as the backend. So please install the corresponding libraries. The instruction that you need to install the library should be shown in the error message. For Debian/Ubuntu:

sudo apt-get install libgtk2.0-dev

Meanwhile, it is also possible to compile everything from source so that OpenCV will auto-detect and support (if they have the corresponding implementation) the backend you have on your system.

The instruction to compile everything from source is given in the very first line of the file, and I copied it here for you:

If you find the precompiled binaries do not suit your needs (e.g., perhaps you need OpenCV to be compiled with FFmpeg to handle more video formats.), it’s possible to override the behaviour by setting the environment variable EVISION_PREFER_PRECOMPILED to false, and then please delete _build/${MIX_ENV}/lib/evision and recompile evision

1 Like

Show function gives this error ??

** (ArgumentError) argument error
    (evision 0.1.4-dev) :evision_nif.imshow([winname: "image", mat: {:ok, #Reference<0.4008954437.2381709314.47653>}])
    (evision 0.1.4-dev) lib/evision_highgui.ex:28: Evision.HighGui.imshow!/2
    (task1b_number_detection 0.1.0) lib/task1b_number_detection.ex:22:

This is my dependencies
{:evision, “~> 0.1.0-dev”, github: “cocoa-xu/evision”, branch: “main”},
{:nx, “~> 0.2”},
{:tesseract_ocr, “~> 0.1.5”}

Hi, some dependencies are outdated, please use the following ones

{:evision, "~> 0.1.14"},
{:nx, "~> 0.3"},
{:tesseract_ocr, "~> 0.1.5"}

Also, if you are using it on Linux, please note that the precompiled evision binary is not compiled with GTK. Please set the environment variable EVISION_PREFER_PRECOMPILED to false. Or, you can use the precompiled version and Evision.Wx.imshow/2 (instead of Evision.HighGui.imshow/2) if Erlang on your system is compiled with wxWidgets.

I have ran “export EVISION_PREFER_PRECOMPILED=false” to set environment variable and deleted _bulid file for mix compile but every time I get this error

== Compilation error in file lib/smartcell/ml_traindata.ex ==
** (CompileError) lib/smartcell/ml_traindata.ex:3: module Kino.JS is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
(elixir 1.13.4) expanding macro: Kernel.use/2
lib/smartcell/ml_traindata.ex:3: Evision.SmartCell.ML.TrainData (module)
(elixir 1.13.4) expanding macro: Kernel.if/2
lib/smartcell/ml_traindata.ex:2: Evision.SmartCell.ML.TrainData (module)

Sorry but I need more information because the problem you described cannot be reproduced locally or on CI.

Have you tried mix deps.update kino? Or could you please copy and paste your mix.exs file so that I can try to reproduce the issue?

#mix.exs file

defmodule Task1bNumberDetection.MixProject do
  use Mix.Project

  def project do
      app: :task1b_number_detection,
      version: "0.1.0",
      start_permanent: Mix.env() == :prod,
      deps: deps()

  def application do
      extra_applications: [:logger]

  defp deps do
      {:evision, "~> 0.1.14"},
      {:nx, "~> 0.3.0"},
      {:tesseract_ocr, "~> 0.1.5"}

evision lists kino as optional: true in its mix.exs, which means it can work with Kino but does not require it. If you’re using Kino, you’ll want to list it explicitly in your mix.exs.

However, something peculiar is going on: the line that’s failing for you is protected by a guard that should keep it from running:

If Kino isn’t loaded, it shouldn’t even try to run line 3… :thinking:

Got it, and fix is on the way. I’ll let you know 0.1.15 is released.

1 Like

Yeah, that’s also what I thought… maybe I need to read the implementation of use in Elixir.

But anyway, I’ll adhere to elixir’s behaviour and make :kino a required dependency for now.

v0.1.15 is available on hex now. :slight_smile: @gaurav136

Thank You :smiley: it’s now working as expected

The detailed reason and explanation can be found on my blog: Conditional compilation with “if” and “use” in Elixir

I’m too sleepy right now I’ll probably format it to markdown later and then post it on elixirforum :sleeping:

1 Like