The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Cv - helps you to make something around computer vision.

SYNOPSIS

 use Cv;
 
 my $image = Cv->LoadImage("/path/to/image", CV_LOAD_IMAGE_COLOR);
 $image->ShowImage("image");
 Cv->WaitKey;

DESCRIPTION

Cv is a Perl interface to OpenCV computer vision library that originally developed by Intel. I am making this module, to use the computer vision more easily like a slogan of perl "Easy things should be easy, hard things should be possible."

Cv is developing as follows. I am not coming satisfactorily. I am learning Perl and OpenCV. I hope to grow it to an interesting module.

  • The memory is deallocated by destroying the object.

  • The function name is usually formed by omitting cv prefix.

  • The argument of the function is a named argument that is always preceded by a hyphen. Please see an OpenCV reference manual http://opencv.willowgarage.com/documentation/ about a name of an argument.

  • You can also use positional arguments, but you can be confused because different from prototype of C in order of arguments.

     # C prototype
     IplImage* cvLoadImage(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR)
    
     # Named argument
     my $image = Cv->LoadImage(-filename => $filename,
                               -iscolor => CV_LOAD_IMAGE_COLOR);
    
     # Optional arguments enable you to omit arguments for some parameters.
     my $image = Cv->LoadImage(-filename => $filename);
    
     # Positional arguments
     my $image = Cv->LoadImage($filename, CV_LOAD_IMAGE_COLOR);

SAMPLES

The following samples demonstrates how to use Cv.

Images and Arrays

Functions of accessing elements and sub-arrays. And IplImage processing.

  • Most functions return -dst that is the object. Excludes the return value is used, like a GetD, etc.

  • The object is created with the same attribute of -src if you don't specify -dst.

 my $image = Cv->LoadImage("/path/to/image", CV_LOAD_IMAGE_COLOR);
 $image->SetImageROI([0, 0, $image->width/2, $image->width/2]);
 my $gray = $image->CvtColor(CV_RGB2GRAY);
 $image->ResetImageROI;
 $gray->ShowImage("gray");
 Cv->WaitKey;

The next function is usable.

 AbsDiff AbsDiffS Acc AdaptiveThreshold Add AddS AddWeighted Affine And
 AndS BoxPoints CalcGlobalOrientation CalcMotionGradient
 CalcOpticalFlowPyrLK CalibrateCamera2 Calibration CamShift Canny Ceil
 Circle Cmp CmpS ComputeCorrespondEpilines Convert ConvertScale
 ConvertScaleAbs Copy CopyMakeBorder CrossProduct CvConnectedComp
 CvtColor CvtScale CvtScaleAbs DFT Dilate DistTransform Div
 DrawChessboardCorners Ellipse EllipseBox EndFindContours EqualizeHist
 Erode Error Exp ExtractSURF FillConvexPoly FillPoly Filter2D
 FindChessboardCorners FindContours FindCornerSubPix
 FindExtrinsicCameraParams2 FindFundamentalMat FindNextContour
 FitEllipse FitLine Flip FloodFill Floor GEMM Get1D Get2D Get3D GetCol
 GetCols GetD GetDimSize GetDims GetElemType GetOptimalDFTSize
 GetReal1D GetReal2D GetReal3D GetRealD GetRectSubPix GetRow GetRows
 GetSize GetSubRect GoodFeaturesToTrack HaarDetectObjects HoughCircles
 HoughLines2 InRange InRangeS InitUndistortMap InitUndistortRectifyMap
 Inpaint Integral Invert KMeans2 LUT Laplace Line Load LoadCascade Log
 MatMul MatMulAdd MatchTemplate Max MaxRect MaxS Merge Min MinAreaRect2
 MinMaxLoc MinS Moments MorphologyEx Mul Norm Normalize Not Or OrS
 PolyLine Pow PutText PyrDown PyrMeanShiftFiltering PyrUp Rectangle
 Reduce Remap Resize Round RunningAvg SURFParams Scale ScaleAdd Set
 Set1D Set2D Set3D SetD SetIdentity SetReal1D SetReal2D SetReal3D
 SetRealD SetZero ShowImage Smooth Sobel Split StartFindContours
 StereoCalibrate StereoRectify StereoRectifyUncalibrated Sub SubRS SubS
 SubstituteContour Threshold Undistort2 UndistortPoints
 UpdateMotionHistory Watershed Xor XorS Zero height show width

GUI

Basic GUI functions (Window, Trackbar, Mouse).

 my $img = Cv->CreateImage([320, 240], 8, 3)->Zero;
 my $win = Cv->NamedWindow("Window");
 
 my $value = 0;
 $win->CreateTrackbar(
     -trackbar_name => "value",
     -value => \$value,
     -count => 100,
     -on_change => \&on_change,
     );

 $win->SetMouseCallback(-callback => \&on_mouse, -param => 123);
 
 $win->ShowImage($img);
 $img->WaitKey;
 
 sub on_change {
     print "[on_change]: value = $value\n";
 }

 sub on_mouse {
     print "[on_mouse]: event = $_[0], x = $_[1], y = $_[2], flags = $_[3], param = $_[4]\n";
 }

Text rendering functions.

 my $image = Cv->CreateImage(-size => [ 320, 240 ], -depth => 8, -channels => 3);
 $image->Set(-value => [ 0, 0, 0 ]);
 my $text = "Hello, OpenCV";
 my $font = Cv->InitFont(
     -font_face => CV_FONT_HERSHEY_COMPLEX,
     -hscale    => 0.5,
     -vscale    => 0.5,
     -shear     => 0,
     -thickness => 1,
     -line_type => 16,
     );
 $font->PutText(-img => $image, -text => $text, -org => [100, 100]);

Matrix and Sequence

The following sample is minaria.c attached to OpenCV samples. This sample displays a minimum rectangle and a minimum circle that encloses all the points.

 my $ARRAY = 1;                    # 1: Cv:Mat, 0: Cv::Seq
 
 my $win = Cv->NamedWindow(-name => "rect & circle", -flags => 1);
 my $img = Cv->new(-size => [ 500, 500 ], -depth => 8, -channels => 3);
 my $mem = Cv->CreateMemStorage;
 
 while (1) {
     my $p = undef;
     my $count = rand(100) + 1;
 
     if ($ARRAY) {
         $p = Cv->CreateMat(
             -rows => 1,
             -cols => $count,
             -type => CV_32SC2,    # as cvPoint
             );
     } else {
         use Cv::Seq::Point;
         $p = Cv::Seq::Point->new(
             -seq_flags => CV_SEQ_KIND_GENERIC | CV_32SC2,
             -storage => $mem,
             );
     }
 
     foreach (0 .. $count - 1) {
         my $pt = cvPoint(
             -x => rand($img->width/2)  + $img->width/4,
             -y => rand($img->height/2) + $img->height/4,
             );
         if ($ARRAY) {
             $p->SetD(-idx => $_, -value => $pt);
         } else {
             $p->Push(-element => $pt);
         }
     }
 
     $img->Zero;
     foreach (0 .. $count - 1) {
         my $pt;
         if ($ARRAY) {
             $pt = $p->GetD(-idx => $_);
         } else {
             $pt = $p->GetSeqElem(-index => $_);
         }
         $img->Circle(
             -center => $pt,
             -radius => 2,
             -color => CV_RGB(255, 0, 0),
             -thickness => CV_FILLED,
             -line_type => CV_AA,
             -shift => 0,
             );
     }
 
     my @b = Cv->BoxPoints(-box => $p->MinAreaRect2());
     foreach ([ $b[0], $b[1] ], [ $b[1], $b[2] ],
              [ $b[2], $b[3] ], [ $b[3], $b[0] ]) {
         $img->Line(
             -pt1 => $_->[0],
             -pt2 => $_->[1],
             -color => CV_RGB(0, 255, 0),
             -thickness => 1,
             -line_type => CV_AA,
             -shift => 0,
             );
     }
 
     $img->Circle(
         -circle => $p->MinEnclosingCircle(),
         -color => CV_RGB(255, 255, 0),
         -thickness => 1,
         -line_type => CV_AA,
         -shift => 0,
         );
 
     $win->ShowImage(-image => $img);
     my $key = $win->WaitKey;
     $key &= 0x7f if $key >= 0;
     last if $key == 27 || $key == ord('q') || $key == ord('Q'); # 'ESC'
 }

Capture

The following sample capture and displays the image from camera.

 my $capture = Cv->CreateCameraCapture(0);
 die "can't create capture" unless $capture;

 while (my $frame = $capture->QueryFrame) {
     $frame->ShowImage;
     Cv->WaitKey(33);
 }

Histograms

The following sample displays the histogram of each RGB of three channel color image.

 my @planes = map { Cv->new(scalar $img->GetSize, $img->depth, 1) } (0..2);
 $img->Split(-dst => \@planes);
 
 my @hists = map {
     Cv->CreateHist(-sizes => [256], -type => CV_HIST_ARRAY)
         ->Calc(-images => [$_])
     } @planes;
 
 my ($width, $height) = (256, 200);
 my @himages = map { Cv->new([$width, $height], 8, 3)->Zero->Not } (0..2);
 my @mm = map { $_->GetMinMaxHistValue } @hists;
 
 map {
     $hists[$_]->ScaleHist(-scale => $height/$mm[$_]->{max}{val})
         if $mm[$_]->{max}{val};
 } (0..2);
 
 my $bin = Cv->Round($width/256);
 for my $i (0..255) {
     my ($x, $y) = ($i*$bin, $height);
     my $pt1 = [$x, $y];
     my @pt2 = map { [$x+$bin, $y - $hists[$_]->QueryHistValue([$i])] } (0..2);
     $himages[0]->Rectangle($pt1, $pt2[0], [$i, 0, 0] );
     $himages[1]->Rectangle($pt1, $pt2[1], [0, $i, 0] );
     $himages[2]->Rectangle($pt1, $pt2[2], [0, 0, $i] );
 }
 
 $dst = Cv->new([$width, $height*3], 8, 3);
 for (0..2) {
     my $roi = [0, $height*$_, $width, $height];
     $himages[$_]->Copy($dst->SetImageROI($roi));
 }
 $dst->ResetImageROI;
 $dst->ShowImage('Histogram');
 $img->ShowImage('Image');
 Cv->WaitKey(1000);

The next function is usable.

 CalcBackProject CalcBackProjectPatch CalcHist CalcPGH ClearHist
 CompareHist CopyHist GetMinMaxHistValue NormalizeHist QueryHistValue
 ReleaseHist ScaleHist ThreshHist

FileStorage

The following samples are examples that save data by cvWrite.

 my $filename = "/path/to/file";
 my $fs = Cv->OpenFileStorage(-filename => $filename,
                              -flags => CV_STORAGE_WRITE);
 my $mat = Cv->CreateMat(3, 3, CV_32F);
 $mat->SetIdentity;
 $fs->Write("MAT", $mat);

The following samples are examples that save data by cvWrite.

 my $fs = Cv->OpenFileStorage(-filename => $filename,
                              -flags => CV_STORAGE_READ);
 my $param = $fs->GetFileNodeByName("MAT");
 my $ = $fs->Read($param);

Sorry. Only the following function can be used still.

 Write Read GetFileNodeByName

Contour

The following sample finds the contours, and does highlight display.

 my $storage = Cv->CreateMemStorage;
 my $gray = $image->CvtColor(CV_RGB2GRAY);
 my $canny = $gray->PyrDown->PyrUp->Canny(-dst => $gray->new);
 for (my $contour = $canny->FindContours(-storage => $storage);
      $contour; $contour = $contour->h_next) {
   $contour->Draw(-image => $image, -max_level => 0, -thickness => 3,
                  -external_color => [ rand(255), rand(255), rand(255) ],
                  -hole_color => CV_RGB(255, 255, 255));
   $image->ShowImage("contour");
   last if Cv->WaitKey(100) >= 0;
 }

RNG

The following sample sets and displays a random value to all pixels.

 my $rng = Cv->RNG(-1);
 my $img = Cv->CreateImage([ 320, 240 ], IPL_DEPTH_8U, 3);
 for (0..10) {
     $rng->RandArr(
         -arr => $img,
         -dist_type => CV_RAND_NORMAL,
         -param1 => scalar cvScalarAll(0),
         -param2 => scalar cvScalarAll(255),
     );
     $img->NamedWindow->ShowImage;
     Cv->WaitKey(100);
 }

Random number generator.

Experimental

The following are experimental. See sample code, please.

  • Hough

    HoughCircles, HoughLines, HoughLines2

  • Moments

    Accessing Moments and HuMoments structure

  • ConvKernel

    create a structuring element in the morphological operations

  • BGCodebook

    The codebook background model

  • HaarDetectObjects

    Detects objects in the image

  • StereoBMState

    The structure for block matching stereo correspondence algorithm

  • Kalman

    Allocates Kalman filter structure

  • MotionHistory

    Segments whole motion into separate moving parts

EXPORT

Cv::Constant

CV_*, IPL_*

Cv::CxCore

cvBox, cvBox2D, cvBoxPoints, cvCeil, cvFloor, cvIndex, cvMaxRect, cvPoint, cvRealScalar, cvRect, cvRound, cvScalar, cvScalarAll, cvSize, cvSlice, cvTermCriteria, CV_RGB, CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION, CV_VERSION,

BUGS

  • All functions of OpenCV cannot be used.

  • To use, Some functions need modules other than Cv, to use it. (Ex. Cv::Seq::Point etc.)

  • I am still considering of interface of the arguments. So, these might be changed.

  • CvCopyHist of OpenCV2.0 cannot return a correct object.

SEE ALSO

http://sourceforge.net/projects/opencvlibrary/

AUTHOR

Yuta Masuda, <yuta.masuda@newdaysys.co.jp>

LICENCE

Copyright (c) 2010 by Masuda Yuta.

All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.