Dylan  Iqbal

Dylan Iqbal

1559797064

Computer Vision Using OpenCV

Computer Vision Using OpenCV. This article has all the basics you need to get started with Computer Vision.

OpenCV Python Tutorial

In this OpenCV Python tutorial, we will be covering various aspects of computer vision using OpenCV in Python. OpenCV has been a vital part in the development of software for a long time. Learning OpenCV is a good way for developers to improve aspects of coding and help them build a software development career.

What Is Computer Vision?

To simplify the answer to this, let’s consider a scenario.

Let’s say you and your friends went on a vacation and you uploaded a bunch of pictures to Facebook. But now it’s going to take time to find your friends’ faces and tag them in each and every picture. Actually, Facebook is intelligent enough to tag people for you.

So, how do you think the auto-tag feature works? In simple terms, it works through computer vision.

Computer vision is an interdisciplinary field that deals with how computers can be made to gain a high-level understanding from digital images or videos.

The idea here is to automate tasks that the human visual systems can do. So, a computer should be able to recognize objects like the face of a human being or a lamppost or even a statue.

How Does A Computer Read An Image?

Consider the below image:

We can figure out that it is an image of the New York skyline. But can a computer find this out all on its own? The answer is no!

The computer reads any image as a range of values between 0 and 255.

For any color image, there are 3 primary channels — red, green and blue. How it works is pretty simple.

A matrix is formed for every primary color, and later, these matrices combine to provide a pixel value for the individual R, G, and B colors.

Each element of the matrices provides data pertaining to the intensity of brightness of the pixel.

Consider the following image:

As shown, the size of the image here can be calculated as B x A x 3.

Note: For a black and white image, there is only one single channel.

Now let’s look at what OpenCV actually is.

What Is OpenCV?

OpenCV is a Python library that was designed to solve computer vision problems. OpenCV was originally developed in 1999 by Intel, but later, it was supported by Willow Garage. It supports a wide variety of programming languages such as C++, Python, Java, etc. Support for multiple platforms including Windows, Linux, and MacOS.

OpenCV Python is nothing but a wrapper class for the original C++ library to be used with Python. Using this, all of the OpenCV array structures gets converted to/from NumPy arrays. This makes it easier to integrate it with other libraries that use NumPy. For example, libraries such as SciPy and Matplotlib.

Basic Operations With OpenCV?

Let’s look at various concepts ranging from loading images to resizing them and so on.

Loading an Image Using OpenCV

Import cv2

# colored Image

Img = cv2.imread ("Penguins.jpg",1)

# Black and White (gray scale)

Img_1 = cv2.imread ("Penguins.jpg",0)

As seen in the above piece of code, the first requirement is to import the OpenCV module.

Later, we can read the image using imread module. The 1 in the parameters denotes that it is a color image. If the parameter was 0 instead of 1, it would mean that the image being imported is a black and white image. The name of the image here is “Penguins.” Pretty straightforward, right?

Image Shape/Resolution:

We can make use of the shape sub-function to print out the shape of the image. Check out the below image:

Import cv2

# Black and White (gray scale)

Img = cv2.imread ("Penguins.jpg",0)

Print(img.shape)

By shape of the image, we mean the shape of the NumPy array. As you see from executing the code, the matrix consists of 768 rows and 1024 columns.

Displaying the image:

Displaying an image using OpenCV is pretty simple and straightforward. Consider the below image:

import cv2

# Black and White (gray scale)

Img = cv2.imread ("Penguins.jpg",0)

cv2.imshow("Penguins", img)

cv2.waitKey(0)

# cv2.waitKey(2000)

cv2.destroyAllWindows()

As you can see, we first import the image using imread. We require a window output to display the images, right?

Later, we wait for a user event. waitKey makes the window static until the user presses a key. The parameter passed to it is the time in milliseconds.

And lastly, we use destroyAllWindows to close the window based on the waitForKey parameter.

Resizing the image:

Similarly, resizing an image is very easy. Here’s another code snippet:

import cv2

# Black and White (gray scale)

img = cv2.imread ("Penguins.jpg",0)

resized_image = cv2.resize(img, (650,500))

cv2.imshow("Penguins", resized_image)

cv2.waitKey(0)

cv2.destroyAllWindows()

Here, the resize function is used to resize an image to the desired shape. The parameter here is the shape of the new resized image.

The rest of the code is pretty simple compared to the previous one, correct?

I am sure you guys are curious to look at the penguins, right? This is the image we were looking to output all this while!

There is another way to pass the parameters to the resize function. Check out the following representation:

Resized_image = cv2.resize(img, int(img.shape[1]/2), int(img.shape[0]/2)))

Here, we get the new image shape to be half of that of the original image.

Face Detection Using OpenCV

This seems complex at first, but it is very easy. Let me walk you through the entire process, and you will feel the same.

Step 1: Considering our prerequisites. We will require an image, to begin with. Later, we need to create a cascade classifier that will eventually give us the features of the face.

Step 2: This step involves making use of OpenCV, which will read the image and the features file. So at this point, there are NumPy arrays at the primary data points.

All we need to do is to search for the row and column values of the face NumPy ndarray. This is the array with the face rectangle coordinates.

Step 3: This final step involves displaying the image with the rectangular face box.

Check out the following image, here I have summarized the 3 steps in the form of an image for easier readability:

Pretty straightforward, right?

First, we create a CascadeClassifier object to extract the features of the face as explained earlier. The path to the XML file that contains the face features is the parameter here.

The next step would be to read an image with a face on it and convert it into a black and white image using COLOR_BGR2GREY. Followed by this, we search for the coordinates for the image. This is done using detectMultiScale.

What coordinates, you ask? It’s the coordinates for the face rectangle. The scaleFactor is used to decrease the shape value by 5 percent until the face is found. So, on the whole, the smaller the value, the greater the accuracy.

Finally, the face is printed on the window.

Adding the Rectangular Face Box:

This logic is very simple — as simple as making use of a for loop statement. Check out the following image:

We define the method to create a rectangle using **cv2.rectangle ** by passing parameters such as the image object, RGB values of the box outline and the width of the rectangle.

Let us check out the entire code for face detection:

import cv2

# Create a CascadeClassifier Object
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

# Reading the image as it is
img = cv2.imread("photo.jpg")

# Reading the image as gray scale image
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# Search the co-ordintes of the image
faces = face_cascade.detectMultiScale(gray_img, scaleFactor = 1.05,
                                      minNeighbors=5)
for x,y,w,h in faces:
    img = cv2.rectangle(img, (x,y), (x+w,y+h),(0,255,0),3)

resized = cv2.resize(img, (int(img.shape[1]/7),int(img.shape[0]/7)))

cv2.imshow("Gray", resized)

cv2.waitKey(0)

cv2.destroyAllWindows()

Capturing Videos Using OpenCV

Capturing videos using OpenCV is pretty simple as well. The following loop will give you a better idea. Check it out:

The images are read one-by-one, hence videos are produced due to fast processing of frames, which makes the individual images move.

Check out the following image:

First, we import the OpenCV library as usual. Next, we have a method called VideoCapture, which is used to create the VideoCapture object. This method is used to trigger the camera on the user’s machine. The parameter to this function denotes if the program should make use of the built-in camera or an add-on camera. ‘0’ denotes the built-in camera in this case.

And lastly, the release method is used to release the camera in a few milliseconds.

When you go ahead and type in and try to execute the above code, you will notice that the camera light switches on for a split second and turns off later. Why does this happen?

This happens because there is no time delay to keep the camera functional.

Looking at the above code, we have a new line called time.sleep(3). This makes the script stop for 3 seconds. Note that the parameter passed is the time in seconds. So, when the code is executed, the webcam will be turned on for 3 seconds.

Adding the Window:

Adding a window to show the video output is pretty simple and can be compared to the same methods used for images. However, there is a slight change. Check out the following code:

I am pretty sure you can make the most sense from the above code apart from one or two lines.

Here, we have defined a NumPy array that we use to represent the first image that the video captures. This is stored in the frame array.

We also have check. This is a boolean datatype that returns True if Python is able to access and read the VideoCapture object.

Check out the output below:

As you can see, we got the output as True and the part of the frame array is printed.

But we need to read the first frame/image of the video to begin, correct?

To do exactly that, we need to first create a frame object that will read the images of the VideoCapture object.

As seen above, the imshow method is used to capture the first frame of the video.

All this while, we have tried to capture the first image/frame of the video.

So how do we go about capturing the video instead of the first image in OpenCV?

Capturing Video Directly:

In order to capture the video, we will be using the while loop. The while condition will be such that unless ‘check’ is True, then Python will display the frames.

Here’s the code snippet image:

We make use of the cvtColor function to convert each frame into a grey-scale image as explained earlier.

waitKey(1) will make sure to generate a new frame after every millisecond of a gap.

It is important to note that the while loop is completely in play to help iterate through the frames and eventually display the video.

There is a user event trigger here as well. Once the ‘q’ key is pressed by the user, the program window closes.

OpenCV is pretty easy to grasp, right? I personally love how good the readability is and how quickly a beginner can get started working with OpenCV.

Use Case: Motion Detector Using OpenCV

Problem Statement

You have been approached by a company that is studying human behavior. Your task is to give them a webcam that can detect motion in front of it. This should return a graph, and this graph should contain how long the human/object was in front of the camera.

So, now that we have defined our problem statement, we need to build a solution logic to approach the problem in a structured way.

Consider the below diagram:

Initially, we save the image in a particular frame.

The next step involves converting the image to a Gaussian blur image. This is done to ensure we calculate a palpable difference between the blurred image and the actual image.

At this point, the image is still not an object. We define a threshold to remove blemishes, such as shadows and other noises in the image.

Borders for the object are defined later and we add a rectangular box around the object as we discussed earlier on in the tutorial.

Lastly, we calculate the time at which the object appears and exits the frame.

Pretty easy, right?

Here’s the code snippet:

The same principle follows through here as well. We first import the package and create the VideoCapture object to ensure we capture video using the webcam.

The while loop iterates through the individual frames of the video. We convert the color frame to a grey-scale image and later convert this grey-scale image to Gaussian blur.

We need to store the first image/frame of the video, correct? We make use of the if statement for this purpose alone.

Now, let us dive into a little more code:

We make use of the absdiff function to calculate the difference between the first occurring frame and all the other frames.

The threshold function provides a threshold value such that it will convert the difference value with less than 30 to black. If the difference is greater than 30, it will convert those pixels to white color. THRESH_BINARY is used for this purpose.

Later, we make use of the findContours function to define the contour area for our image. And we add in the borders at this stage as well.

The contourArea function, as previously explained, removes the noises and the shadows. To make it simple, it will keep only that part white, which has an area greater than 1000 pixels as we’ve defined for that.

Later, we create a rectangular box around our object in the working frame.

And followed by this is this simple code:

As discussed earlier, the frame changes every 1 millisecond, and when the user enters ‘q’, the loop breaks and the window closes.

One thing that remains with our use-case is that we need to calculate the time for which the object was in front of the camera.

Calculating the Time:

We make use of DataFrame to store the time values during which object detection and movement appear in the frame.

Followed by that is the VideoCapture function we explained earlier. But here, we have a flag bit we call status. We use this status at the beginning of the recording to be zero, as the object is not initially visible.

We will change the status flag to 1 when the object is being detected as shown in the above figure. Pretty simple, right?

We are going to make a list of the status for every scanned frame and later record the date and time using datetime in a list if and where a change occurs.

We store the time values in a DataFrame as shown in the above explanatory diagram. We’ll conclude by writing the DataFrame to a CSV file as shown.

Plotting the Motion Detection Graph:

The final step in our use-case is to display the results. We are displaying the graph, which denotes the motion on 2-axes. Consider the below code:

To begin with, we import the DataFrame from the motion_detector.py file.

The next step involves converting time to a readable string format, which can be parsed.

Lastly, the DataFrame of time values is plotted on the browser using Bokeh plots.

Output:

Conclusion

I hope this OpenCV Python tutorial helps you in learning all the fundamentals needed to get started with OpenCV using Python.

This will be very handy when you are trying to develop applications that require image recognition and similar principles. Now, you should also be able to use these concepts to develop applications easily with the help of OpenCV in Python.

#python #opencv

What is GEEK

Buddha Community

Computer Vision Using OpenCV
Chloe  Butler

Chloe Butler

1667425440

Pdf2gerb: Perl Script Converts PDF Files to Gerber format

pdf2gerb

Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.


pdf2gerb_cfg.pm

#Pdf2Gerb config settings:
#Put this file in same folder/directory as pdf2gerb.pl itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)


##############################################################################################
#configurable settings:
#change values here instead of in main pfg2gerb.pl file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)}Pdf2Gerb.pl ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
(
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
#traces:
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .012,
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .025,
    .030,  #heavy-current traces; be careful with these ones!
    .040,
    .050,
    .060,
    .080,
    .100,
    .120,
);
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
{
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects
};

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
{
    CIRCLE_ADJUST_MINX => 0,
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    CIRCLE_ADJUST_MAXY => 0,
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found
};

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
{
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
};
    
#number of elements in each shape type:
use constant
{
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
};
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
our %SHAPELEN =
(
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,
);

#panelization:
#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#############################################################################################
#junk/experiment:

#use Package::Constants;
#use Exporter qw(import); #https://perldoc.perl.org/Exporter.html

#my $caller = "pdf2gerb::";

#sub cfg
#{
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;
#}

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #https://www.perlmonks.org/?node_id=1072691; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code: https://github.com/swannman/pdf2gerb

License: GPL-3.0 license

#perl 

Computer Vision using Mediapipe

Computer vision can be defined as a field of artificial intelligence that trains computers to interpret and understand the visual world. Using digital images from cameras and videos and deep learning models, machines can accurately identify and classify objects and then react to what they “see.”

Computer vision is an interdisciplinary scientific field that deals with how computers can gain high-level understanding from digital images or videos.

In today’s world computer vision is very useful in many fields such as — :

*_ Inventory management — : _**In the case of inventory management, the applications can be in the field of security camera image analysis where a computer vision algorithm can generate a very accurate estimate of the items available in the store. Another field can be Analyzing the use of shelf space to identify suboptimal configurations.

* **Manufacturing — : **In the Field of manufacturing Computer vision can help in **predictive maintenance **of the machines.

*** Healthcare — : In the field of healthcare computer Vision can be used in medical image analysis.** Images from CT scans and X-rays are analyzed to find anomalies such as tumors or search for signs of neurological illnesses.

* **Autonomous vehicles — : **The field of computer vision plays a central role in the domain of autonomous vehicles since it allows them to perceive and understand the environment around them in order to operate correctly. One of the most exciting challenges in computer vision is object detection in images and videos. This involves locating a varying number of objects and the ability to classify them, in order to distinguish if an object is a traffic light, a car, or a person, as in the video below.

#computer-vision #opencv #mediapipe #anaconda-navigator #python #computer vision using mediapipe

Gussie  Hansen

Gussie Hansen

1616140422

9 Most important inbuilt functions in OpenCV for Computer Vision

OpenCV is a popular Computer Vision library mostly used for real-time applications. In this blog, we go through the 9 most frequently used OpenCV functions to use the library efficiently along with code examples.

Color to GrayScale

2. Blurring an image using GuassianBlur

3. Edge Cascade

4. Dilation of the cascaded image .

5. Resize and cropping the image

6. Determining contours in an image

7. Splitting an image into its respective RED, GREEN, and BLUE parts .

8. BITWISE operators in OpenCV.

9. Plotting a histogram of an image.

#computer-vision #opencv-python #machine-learning #python #opencv

Track Distance and Angle of an Object Using Computer Vision

Introduction

Tracking the distance and angle of an object has many practical uses, especially in robotics. This tutorial explains how to get an accurate distance and angle measurement, even when the target is at a strong angle from the camera.

Before we start

Download the demo here!

How to accurately track distance at any angle

Building off this article, we know that we can approximate the distance as long as we have the width of the target in pixels and cm/inches at a known distance.

focal length_ = (known pixel Width * knownDistance) / known width_

Distance (cm/inches/etc.)_ =( known Width * focal length) / pixel Width_

When using width to approximate distance, the width gets smaller at an angle, decreasing the accuracy.

Instead, fitted height should be used to calculate distance, because the fitted height will always stay the same, no matter what angle.

Therefore, to calculate distance using fitted height, use these equations:

focal length_ = (known pixel Height * knownDistance) / known height_

Distance (cm/inches/etc.)_ = (known height * focal length) / pixel height_

This approximation works as long as the height of the target stays the same. Also remember to use fitted height instead of bounding height because fitted height tilts with the object and bounding height does not.

#object-detection #opencv #computer-vision #python #computer-science

A Simple HDR Implementation on OpenCV Python

Learn how to create a high dynamic range (HDR) image using Python and OpenCV

HDR images encompass the information of multiple pictures with different exposures. In a scene which the source of light is uneven, a single shot may overexpose certain areas of the image and details will be lost due to elevated brightness. Conversely, this picture may also present underexposed areas which will also lead to information loss.

To create an HDR image you will need:

  1. Take pictures with different exposures. Minimum of 2, generally 3, you can use more than 3 images but it will take a lot of CPU resources.
  2. Align the images. Even if you use a tripod you will need to perform this step (we are talking about pixel level alignment). Not properly aligning your image will lead to artifacts and ‘ghosts’ in your HDR image.
  3. Merge the aligned images into one.
  4. Perform tone mapping on the merged image. In nature the minimum possible brightness is zero but the maximum is not limited to 255, in fact there is no limit to it, it can be infinity. For this reason we need to map the image obtained in the third step to a (0, 255) range. This can be achieved with tone mapping.

#hdr #opencv #computer-vision #python #opencv #opencv python