Page 1 of 2

Learning opencv step by step

Posted: Tue Dec 14, 2021 7:00 am
by Antonio Linares
OpenCV stands for "Open Computer Vision"

Why is it so important ? https://youtu.be/p9IsfqNewmE

1. Download and install OpenCV – 4.5.4 for Windows from https://opencv.org/releases/
2. Install it at c:\opencv
3. Copy c:\opencv\build\x64\vc15\bin\opencv_world454.dll to the folder where you are going to build this test

This tutorial requires FWH 64 bits and Microsoft Visual Studio Community.
Edited: Examples posted here don't require FWH 64 at all.

cv1.prg

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   Test()

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <opencv.hpp>

using namespace cv;

HB_FUNC( TEST )
{
   cv::Mat img = imread( "007.jpg" );
   
   namedWindow( "image", WINDOW_AUTOSIZE );
   imshow( "image", img );
   waitKey( 0 );
}

#pragma ENDDUMP


go64.bat

Code: Select all | Expand

@set oldpath=%Path%
@set oldinclude=%INCLUDE%
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
c:\harbour\bin\win\msvc64\hbmk2 cv1.hbp -comp=msvc64
@set Path=%oldpath%
@set INCLUDE=%oldinclude%


cv1.hbp

Code: Select all | Expand

cv1.prg

-cflag=-TP

-Ic:\fwh64\include
-Ic:\opencv\build\include
-Ic:\opencv\build\include\opencv2

-Lc:\fwh64\lib

-lfiveh64
-lfivehc64
-lgdiplus
-lversion
-lOleDlg
-lopencv_world454

-gui

xhb.hbc
hbct.hbc
hbwin.hbc
hbmzip.hbc
hbziparc.hbc
hbfoxpro.hbc

opencvlib.hbp
 


opencvlib.hbp

Code: Select all | Expand

-hbimplib opencv_world454.dll


Save this image as 007.jpg
Image

When you run cv1.exe you get this:
Image

Re: Learning opencv step by step

Posted: Tue Dec 14, 2021 9:21 am
by Antonio Linares
Una vez la prueba de concepto ha funcionado, empezamos a crear el API a usar desde Harbour:

cv1.prg

Code: Select all | Expand

#include "FiveWin.ch"

#define WINDOW_AUTOSIZE 1

function Main()

   local hMat := cv_ImRead( "007.jpg" )

   cv_namedWindow( "window title", WINDOW_AUTOSIZE )
   cv_ImShow( "window title", hMat )
   cv_WaitKey()

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <opencv.hpp>

using namespace cv;

static cv::Mat mat;

HB_FUNC( CV_IMREAD )
{
   mat = imread( hb_parc( 1 ) );

   hb_retptr( &mat );
}

HB_FUNC( CV_NAMEDWINDOW )
{
   namedWindow( hb_parc( 1 ), hb_parnl( 2 ) );
}

HB_FUNC( CV_IMSHOW )
{
   imshow( hb_parc( 1 ), * ( ( cv::Mat * ) hb_parptr( 2 ) ) );
}

HB_FUNC( CV_WAITKEY )
{
   waitKey( hb_parnl( 1 ) );
}

#pragma ENDDUMP

Re: Learning opencv step by step

Posted: Tue Dec 14, 2021 9:30 am
by Antonio Linares
Opcionalmente si no queremos usar el "namespace" (algo propio de C++) podemos cambiar el código así:

Ojo que en cv1.hbp usamos este flag para indicar que queremos construir en modo C++: (desde el 2015 opencv obliga a usar C++)
-cflag=-TP

cv1.prg

Code: Select all | Expand

#include "FiveWin.ch"

#define WINDOW_AUTOSIZE 1

function Main()

   local hMat := cv_ImRead( "007.jpg" )

   cv_namedWindow( "window title", WINDOW_AUTOSIZE )
   cv_ImShow( "window title", hMat )
   cv_WaitKey()

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <opencv.hpp>

// using namespace cv;

static cv::Mat mat;

HB_FUNC( CV_IMREAD )
{
   mat = cv::imread( hb_parc( 1 ) );

   hb_retptr( &mat );
}

HB_FUNC( CV_NAMEDWINDOW )
{
   cv::namedWindow( hb_parc( 1 ), hb_parnl( 2 ) );
}

HB_FUNC( CV_IMSHOW )
{
   cv::imshow( hb_parc( 1 ), * ( ( cv::Mat * ) hb_parptr( 2 ) ) );
}

HB_FUNC( CV_WAITKEY )
{
   cv::waitKey( hb_parnl( 1 ) );
}

#pragma ENDDUMP

Re: Learning opencv step by step

Posted: Tue Dec 14, 2021 11:56 am
by Baxajaun
Muchas gracias Antonio !!!

Probados los tres ejemplos :D

Saludos,

Re: Learning opencv step by step

Posted: Tue Dec 14, 2021 3:23 pm
by Antonio Linares
Next we are going to review the samples provided by opencv:

https://docs.opencv.org/4.5.4/examples.html

Re: Learning opencv step by step

Posted: Tue Dec 14, 2021 7:44 pm
by Antonio Linares
First of all we need to git clone https://github.com/opencv/opencv_contrib being at c:\

We are going to use this go.bat to build the examples using Visual Studio Community:

go.bat

Code: Select all | Expand

@set oldpath=%Path%
@set oldinclude=%INCLUDE%
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
cl /EHsc test1.cpp -Ic:\opencv\build\include -Ic:\opencv_contrib\modules\ximgproc\include c:\opencv\build\x64\vc15\lib\opencv_world454.lib
@set Path=%oldpath%
@set INCLUDE=%oldinclude%


We need to use the cl.exe /EHsc flag cause this:
"/EHsc" specifies that only standard C++ ("synchronous") exceptions will be caught,
and `extern "C"` functions will not throw exceptions.
This is recommended when writing portable, platform-independent code.

Re: Learning opencv step by step

Posted: Tue Dec 14, 2021 8:35 pm
by Antonio Linares
We have two unresolved externals to solve:

test1.obj : error LNK2019: unresolved external symbol "struct cv::Ptr<class cv::ximgproc::EdgeDrawing> __cdecl cv::ximgproc::createEdgeDrawing(void)" (?createEdgeDrawing@ximgproc@cv@@YA?AU?$Ptr@VEdgeDrawing@ximgproc@cv@@@2@XZ) referenced in function main
test1.obj : error LNK2019: unresolved external symbol "struct cv::Ptr<class cv::ximgproc::FastLineDetector> __cdecl cv::ximgproc::createFastLineDetector(int,float,double,double,int,bool)" (?createFastLineDetector@ximgproc@cv@@YA?AU?$Ptr@VFastLineDetector@ximgproc@cv@@@2@HMNNH_N@Z) referenced in function main
test1.exe : fatal error LNK1120: 2 unresolved externals


We need to build the opencv_contrib library this way:
https://github.com/opencv/opencv_contrib#how-to-build-opencv-with-extra-modules

cd opencv_fwh

build.bat

Code: Select all | Expand

@set oldpath=%Path%
@set oldinclude=%INCLUDE%
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
cmake -DOPENCV_EXTRA_MODULES_PATH=c:\opencv_contrib\modules c:\opencv\sources
msbuild OpenCV.sln /p:Configuration=Release /t:Clean,Build
@set Path=%oldpath%
@set INCLUDE=%oldinclude%


Important: Please delete c:\opencv\sources\CMakeCache.txt before running build.bat

Re: Learning opencv step by step

Posted: Wed Dec 15, 2021 9:44 am
by Antonio Linares
Now that we have properly built the opencv contribs we modify go.bat this way to run the examples:

go.bat

Code: Select all | Expand

@set oldpath=%Path%
@set oldinclude=%INCLUDE%
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
cl /EHsc test1.cpp -Ic:\opencv\build\include -Ic:\opencv_contrib\modules\ximgproc\include c:\opencv\build\x64\vc15\lib\opencv_world454.lib c:\opencv_fwh\lib\Release\opencv_ximgproc454.lib
@set Path=%oldpath%
@set INCLUDE=%oldinclude%


test1.cpp contains the source code for the first example https://docs.opencv.org/4.5.4/d1/d9e/fld_lines_8cpp-example.html
Missing DLLs must be copied from c:\opencv_fwh\lib\Release\ to c:\opencv_fwh (where the resulting test1.exe is located)

The example is working fine and amazingly detects the edge lines of a photo:
Image

Re: Learning opencv step by step

Posted: Wed Dec 15, 2021 11:02 am
by Baxajaun
Antonio,

sigue, sigue que yo te sigo.

Muchas gracias.

Saludos,

Re: Learning opencv step by step

Posted: Wed Dec 22, 2021 7:37 am
by Antonio Linares
go.bat

Code: Select all | Expand

@set oldpath=%Path%
@set oldinclude=%INCLUDE%
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
cl /EHsc test1.cpp -Ic:\opencv\build\include -Ic:\opencv_contrib\modules\ximgproc\include -Ic:\opencv_contrib\modules\shape\include c:\opencv\build\x64\vc15\lib\opencv_world454.lib c:\opencv_fwh\lib\Release\opencv_ximgproc454.lib c:\opencv_fwh\lib\Release\opencv_shape454.lib
@set Path=%oldpath%
@set INCLUDE=%oldinclude%


test1.cpp

Code: Select all | Expand

// -*- coding:utf-8; mode:c++; mode:auto-fill; fill-column:80; -*-

/// @file      cascade-classifier.cpp
/// @brief     OpenCV object recognition example.
/// @author    J. Arrieta <juan.arrieta@nablazerolabs.com>
/// @date      October 04, 2017
/// @copyright (c) 2017 Nabla Zero Labs
/// @license   MIT License.
///
/// I wrote this example program for my later reference.
///
/// Compilation:
///
///     clang++ cascade-classifier.cpp -o cascade-classifier \
///     -std=c++1z -Wall -Wextra -Ofast -march=native \
///     -lopencv_objdetect -lopencv_highgui \
///     -lopencv_imgproc -lopencv_core -lopencv_videoio
///
/// The Haar cascade XML description is provided as a command-line argument; the
/// examples I used are in GitHub:
///
///     https://github.com/opencv/opencv/tree/m ... arcascades
///

// C++ Standard Library
#include <cstdlib>
#include <iostream>
#include <vector>

// OpenCV
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>

#define     CV_HAAR_SCALE_IMAGE   2

int main(int argc, char* argv[]) {
  if (argc != 2) {
    std::cerr << "usage: " << argv[0] << " classifier.xml\n";
    std::exit(EXIT_FAILURE);
  }

  // Load a classifier from its XML description
  cv::CascadeClassifier classifier(argv[1]);

  // Prepare a display window
  const char* const window_name{"Facial Recognition Window"};

  cv::namedWindow(window_name, CV_WINDOW_AUTOSIZE);

  // Prepare a video capture device
  cv::VideoCapture capture(0); // `0` means "default video capture"
  if (! capture.isOpened()) {
    std::cerr << "cannot open video capture device\n";
    std::exit(EXIT_FAILURE);
  }

  // Prepare an image where to store the video frames, and an image to store a
  // grayscale version
  cv::Mat image;
  cv::Mat grayscale_image;

  // Prepare a vector where the detected features will be stored
  std::vector<cv::Rect> features;

  // Main loop
  while (capture.read(image) && (! image.empty())) {
    // Create a normalized, gray-scale version of the captured image
    cv::cvtColor(image, grayscale_image, CV_BGR2GRAY);
    cv::equalizeHist(grayscale_image, grayscale_image);

    // Detect the features in the normalized, gray-scale version of the
    // image. You don't need to clear the previously-found features because the
    // detectMultiScale method will clear before adding new features.
    classifier.detectMultiScale(grayscale_image, features, 1.1, 2,
                                0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));

    // Draw each feature as a separate green rectangle
    for (auto&& feature : features) {
      cv::rectangle(image, feature, cv::Scalar(0, 255, 0), 2);
    }

    // Show the captured image and the detected features
    cv::imshow(window_name, image);

    // Wait for input or process the next frame
    switch (cv::waitKey(10)) {
      case 'q':
        std::exit(EXIT_SUCCESS);
      case 'Q':
        std::exit(EXIT_SUCCESS);
      default:
        break;
    }
  }
  return EXIT_SUCCESS;
}


Usage:
test1.exe c:\opencv\sources\data\haarcascades\haarcascade_frontalface_alt.xml

Results: a window is opened, showing the camera and it recognizes your face :-)
Image

Re: Learning opencv step by step

Posted: Wed Dec 22, 2021 11:04 am
by Antonio Linares
Next we need to learn how to create our own Haar Cascade:

https://youtu.be/jG3bu0tjFbk

Image

Re: Learning opencv step by step

Posted: Wed Dec 22, 2021 11:24 am
by Antonio Linares
100 x 100 for negatives

50 x 50 for positives

Re: Learning opencv step by step

Posted: Wed Dec 22, 2021 11:27 am
by Antonio Linares
Another video:
https://youtu.be/fgx5LDOx4JY

This video provide these utilities to easily create a Haar Cascade file for your own object recognition needs:
https://github.com/FiveTechSoft/FWH_tools/blob/master/anas_haartrain.rar
I copy it here as a safety backup of use for everybody, so it don't get lost (just in case)

With the above tools YOU can create your own XML file that works with the latest example published here (with some changes) !!!

Re: Learning opencv step by step

Posted: Wed Dec 22, 2021 6:32 pm
by Antonio Linares
https://docs.opencv.org/4.x/dc/d88/tutorial_traincascade.html

https://medium.com/analytics-vidhya/haar-cascades-explained-38210e57970d

Code: Select all | Expand

import numpy as np
import cv2
f_cascade = cv2.CascadeClassifier("face.xml")
e_cascade = cv2.CascadeClassifier("eye.xml")
image = cv2.imread("actor.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = f_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
    img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = img[y:y+h, x:x+w]
    eyes = e_cascade.detectMultiScale(roi_gray)
    for (ex,ey,ew,eh) in eyes:
        cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('img',image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Re: Learning opencv step by step

Posted: Thu Dec 23, 2021 5:43 pm
by Antonio Linares
Another software to create Haar Cascades:

https://amin-ahmadi.com/cascade-trainer-gui/