Showing posts with label Image Editing. Show all posts
Showing posts with label Image Editing. Show all posts

Sunday, September 21, 2014

Convert a Monochrome Bitmap Image to a Vector Image

In my last couple of posts I've been writing about barcodes.  When generating them, some programs are able to output a vector image, which makes rescaling them later on easy, but some programs can only output a raster image of pixels.  Converting them to a vector image like an SVG file makes the work-flow easier.  So in this post I'll show how to convert a sample raster image to a vector image.

The sample image to convert is a simple 2D barcode.  It's made up of square elements 2x2 pixels in size.  The processing will be done in Inkscape and GIMP.


barcode
Image to convert to vector
The first step is to enlarge the image.  This is done because the conversion process only works if the edges in the barcode are long and straight.  You may have to try different values until you come across a size that works.  Enlarging the image by 500% was enough in this case.  It's also important to set the interpolation to "None".  This ensures that each pixel in the original image will exactly match a 5x5 group of  pixels in the enlarged image.

instructions
Resize image with no interpolation
Using the colour selector tool in GIMP, click on the colour you want to convert to a vector shape, in this case it's the black of the barcode.

instructions
Select Colour
In GIMP convert the selection to a path.

instructions
Convert Selection to Path
Open the path dialog box and right click on the path just created, then select "Export Path".  This will create an SVG file containing the barcode we are trying to convert.

instructions
Export Path to SVG
When opening the SVG file in Inkscape it'll look wrong.  At first, all that's shown is the outline of barcode.
barcode
SVG with Stroke on and No fill
To correct this, select the object, set the fill to black and then turn off the stroke (outline).  There you have it, an SVG file containing the barcode.  There is a "trace bitmap" function in Inkscape, but it seems to be oriented towards graphics.  When it comes to a doing pixel accurate tracing of an image, this seems to be the easiest way to do it.
barcode
SVG with Fill on and no Stroke

Friday, August 8, 2014

100th Blog Post Retrospective

This is my 100th blog post and to celebrate I thought I'd do what all great TV shows do for milestones episodes, a cheesy clip show.  So I'm going to go through a couple of my favourite posts along with my most popular ones.

OpenGL


My attempt at OpenGL seems to be a good place to start.  I wanted to take the timetables from all our public transport providers and calculate a transit time map for Brisbane.  This would make it easy to visualise what parts of the city were over and under serviced.  To do this I needed a way to visualise the raw data and the results, so I thought I'd write my own viewer.  It used a custom set of tiles from the Open Street Map project I rendered myself and with c++ and openGL it was able to swap in and out tiles with appropriate resolution depending upon the users location in the map.  The project didn't get much further than the results below, I underestimated the scale of the task and overestimated my abilities.  To top it off I lost the project due to a corrupt file, but I was proud of the results nonetheless.  Before this I'd never used OpenGL and had only toyed around with c++.  I also learnt the value of backing up projects.




Off Axis Magnetic Field of a Circular Current Loop


Next up is my second most popular post and the one I'm proudest of.  I wanted to work out the off axis magnetic field of a circular current loop so I could simulate the effect of a magnetic lens on an electron beam.  Not only was the maths difficult, but speaking isn't really my thing.  From memory, the 10 minutes of  video took around 200 takes at recording the audio. If it wasn't me getting tongue tied, it was a noise from outside or something like that.

The video itself was done by combining images created with asymptote.  One drawing was made with a parameter I could change, Linux scripting was then used to render images with different values for the parameter.  That in itself was a nightmare.  The best thing about this post is that I've had a couple comments from people that said it was useful.





Surface Mount Circuit Board


Now for my first surface mount circuit board.  I'd been involved in designing a couple of PCB's for university team projects, but this was the first one I'd designed entirely by myself.  It was also the first time I'd used surface mount parts.  Up until this point I was terrified of them, but after this project I wouldn't use anything else.  The circuit wasn't anything fantastic it was just a breakout board for an MCP9808 temperature sensor and a reason to design a PCB.


PCB with parts in position

Vacuum Pick Up Tool


This project follows on  from designing my first PCB.  I wanted a way to place SMT components.  I'd had reasonable success using tweezers but I wanted to try a vacuum pick up tool.  It works for pick and place machines why not me?  So I made my own tool to see what the advantages and disadvantages were.  I learnt a lot in the process, particularly silver soldering.  I was so happy with my soldering results I polished up the hand piece until it looked like something you'd buy in a jewellery store.  If I were to go back and do it again there are a few things I would change, but it works reasonably well.


Vacuum pick-up tool hand piece

Flaring the End of a PVC Pipe


The popularity of my next post was a bit of a surprise.  I was building a chicken coop for my sister and was short on content so I was just documenting what I was doing during the build.  When it came time to put the down pipe on the gutter I had to flare the end of the PVC pipe so I thought I'd show how I did it.  To date, this post is my most popular and has had almost twice as many hits as my next most popular one, and it's only been up about half as long.  To top it off it took about 20 minutes to photograph and post, my second most popular post was the culmination of about six months of on and off work.


Flaring a PVC pipe

Harmonic Elimination Pulse Width Modulation


This is one of the posts I'm quite proud of as well.  Years before I started this site I came across the concept of harmonic elimination PWM.  It allows a designer to alter the switching times of a PWM signal to control or eliminate certain harmonics in the output waveform.  At the time I worked out the equations, scribbled them down on paper and put them away for later.  That's not much use to anyone, I eventually got around to putting them up so they could be useful to others.  There's lots of information about HEPWM out there, but it's rather high level.  I wanted to give people a starting point with some code to generate the switching waveforms.  There are plenty of ways to slightly alter the design for different requirements, but having an understandable starting point to branch off from is helpful for others.

Octave Code For Generating Harmonic Elimination PWM Waveforms
Fourier Series Of Harmonic Elimination PWM Waveforms
Fourier Series of a Quarter-Wave Symmetric Pulsed Waveform
Harmonic Elimination PWM Comparison and Uses


HEPWM example spectrum


Now it wouldn't be a proper post without me doing something new.  I decided to grab a screen shot of each post including this one and assemble them into a single image.  I thought it would be a nice way to visualise my output over the past three years.  Usually I'd try to use some clever trick to accomplish this, but in this case I just brute forced it.  I took screen shots with the awesome screen shot add-on for chrome.  The images were then batch processed with ImageMagick and Irfanview.  The assembly was done manually.

100 blog posts assembled into one image


So where to now for the blog?  I'd like to do more video, but that's unlikely at this point, so I'll just keep doing what I'm doing.  Writing for the site is a motivator for me, committing to writing a post every 11 days gives me a reason to learn new things and in general keep busy.  Without it, I don't really have a reason to do half the stuff I do.  The blog also has an ulterior motive, it's a bit of a showcase of my abilities.  For someone with no formal qualifications I need all the help I can get to get a job that doesn't bore me to death.  If need be I can use this to prove I'm not just a pretty face :-).

The main reason I keep blogging, apart from innate curiosity, is the occasional bit of feedback I get from people that tell me my posts have helped them.  It's a good feeling that people all over the world have benefited from my work in some way.

Saturday, August 17, 2013

Making Detecting the Angle of Rotated Text More Robust

In my last post I demonstrated how to find the angle of rotated printed text using image processing.  I also mentioned a couple of ways to make the process more robust.  In this post I'll expand on what I meant with a demonstration.

The code and image files associated with this post can be found here.

The basis for this method is that we are only looking for large values in the Radon Transform, this indicates a feature like a line or row of text.  We are also looking for bright features in the gradient of the transform.  This indicates the transition point between a row of text and the white space below it.  By masking out lower values in these two steps, the data points that are more relevant should be highlighted.

The process starts out exactly the same as in my first demonstration, we need to generate the radon transform of the input image.

Radon Transform
Radon Transform from 70 to 110 degrees

As before, a gradient of the radon transform also needs to be calculated.

Vertical Image Gradient
Vertical Image Gradient

This is where things start to change.  A binary mask is generated from the radon transform.  This will only show bright points in the transform and remove other points that are most likely false positives.  The threshold has been set to 20 percent of the maximum value in the radon transform.  A permissive value but it still removes a lot of false positives.

Image Mask
Thresholded Radon Transform

The same process is applied to the gradient image using a a threshold of 10 percent of the maximum value of the gradient.

Image Mask
Thresholded Gradient Image

The two masks are then applied to the original Radon transform by multiplying the masks with the transform.

Radon Transform
Masked Radon Transform

I've created the false colour image below to help demonstrate the process a little better.  The red channel of the image is the mask from the original radon transform.  The Green channel is the mask generated from the gradient image.  The Blue channel is the original Radon Transform.  The only areas that will be visible in the final masked image are areas where the two masks align.  This means that the red and green channel will coincide and create a yellow pixel.  This means the only sections visible in the final image are those that are shades of yellow.  As the intensity of the blue Radon Transform becomes brighter it will turn the yellow pixel white.  (click to enlarge the image)

Radon Transform\
Coloured Transform

As before the images are vertically sumed to create an array of intensities.  The peak intensity will be the rotation angle of the text.  As a comparison, I've show the intensity arrays for the masked and unmasked versions of the process below.
Rotation Angle Graph
Gradient Intensity vs Text Rotation Angle - Unmasked


Rotation Angle Graph
Gradient Intensity vs Text Rotation Angle - Masked

The magnitude of the peaks in the graphs above doesn't matter, what's important is the ratio of the peak to the next largest feature.  In the unmasked version the peak is around 74000 and the next largest peak is around 34000, a ratio of about 2.2.  In the masked version the peak is around 29000 and the next largest peak is around 7000, a ratio of about 4.1.  This make picking the correct feature a lot easier and gives more confidence in the result, which as before comes out at 0.6 degrees.

This is by no means the best that could be done.  I picked the threshold values out of thin air.  They could be determined by trial and error for a particular type of document or they could be dynamic and adjust to the input image.  I'll leave that as an exercise for the reader :-)

Wednesday, March 27, 2013

Cheap Online Digital Microscope

A USB digital microscope that I bought from www.dx.com turned up today.  I wanted something cheap to inspect soldering and PCBs, and at $30 dollars I didn't have much to lose.

Product Box
USB Microscope
The specs say the sensor is 2.0 Mega Pixels, but I can't get anything above 480x640.  Might be a driver issue, but as the included CD was blank and there is no website to download drivers the from, I'm stuck with it.  Doesn't worry me, I was fully expecting problems.  480x640 is fine for my purposes.

Product Box
Microscope Specs

Product Contents
Package Contents

To focus the scope you manually turn a small black wheel on the side of the case.  There is also a button on the camera to take snapshots, which doesn't work.  I assume it would work if had the right drivers, but I prefer to trigger the snapshot from the computer.  This eliminates any movement of the camera that may blur the picture.  The on-off switch controls a ring 8 LEDs around the lens that are used to illuminate the subject.

It comes with a stand that is pretty much useless, which is what I had expected from reviews of similar products.

USB Microscope
Microscope with stand

There isn't much to say, it does what I want and I'm happy with it.  As expected the product isn't great, but it gets me the results I want at a price that I'm happy to pay.

A few sample shots are shown below to get an idea of the results.  Using a ruler as a test shot I was able to determine that there are about 100 pixels per mm or 2.5 pixels per mil which agrees with the track sizing on a couple of the PCBs imaged.

It also looks as if the images are a little over exposed.  I may have to perform some adjustments there.

Surface Mount Resistor
Surface Mount Resistor

Five Dollar Note
Australian Five Dollar Note

2 dollar coin
Back of Australian 2 dollar coin

Steel Ruler
Metal Ruler with 0.5 mm Markings

PCB
Soldermask, Track, and Pads

PCB
Silkscreen

PCB
Silkscreen

Wednesday, March 28, 2012

Resizing EPS Files

This shouldn't be so hard.  All I wanted to do was take an EPS file, print it to a PDF file, while scaling it to fit the page.  Simple right?  Well I had no luck.  Below is a short clip of what I finally came up with to do the job.  It worked like a treat in this case.



Sunday, February 5, 2012

An IDE for Asymptote using inotifywait

Over the last couple of weeks I've been trying to find a way to draw physics diagrams in a style similar to what I've seen in textbooks.  I was hoping for a vector based solution that was open source.  After a few false starts I gave Inkscape a go, but it was hard to get things looking right.  Then I came across Metapost which was close to what I wanted but it was a bit hard to draw 3D diagrams realistically.  Then I found Asymptote, which is inspired by Metapost and is generalised to 3D diagrams.  It's easy to use for someone with a little bit of maths knowledge and produces beautiful results.

As with learning any new language, it's extremely helpful if you have an efficient toolchain that allows you to focus on the job at hand and not on running commands to compile and render things.  The below video demonstrates an easy way to do this using inotifywait from the Inotify-tools package.




while true; do inotifywait -e CLOSE_WRITE $filename; asy -render 0 $filename; done;

The command is straight forward.  An infinite while loop is started, and in it inotifywait is instructed to monitor a file for a CLOSE_WRITE condition, thereby blocking further execution.   When the condition is met the command to render the image is called.

This command could be useful in any situation where you need to monitor if a file is altered.  Anyway, back to learning Asymptote.

Wednesday, December 14, 2011

Converting Image Files to PDFs

Recently I have been processing some image files and needed a way to combine them into a PDF file.  Image files by themselves can get a little bit messy, so it just tidies thing up a little by collating related images.  Don't get me wrong, I still hang on to the originals but PDFs are nicer to actually use.

So here is the situation, I have a folder that contains all the images named sequentially.  The images then need to be converted to PDFs and then combined into one file.  Additionally I want a grayscale version and a colour version.  As usual, the easiest way to do this is with a script in linux.  If you haven't got them already, you will need to run the following commands to install packages for this to work.

sudo apt-get install imagemagick
sudo apt-get install pdftk

Imagemagick is an awesome tool for processing images, particularly when processing batches of them, and Pdftk is a tool kit that allows you to rearrange, remove, and add pages to to pdf files.  With these two tools the following script does the job nicely.

#!/bin/bash

mkdir Col
mkdir BW
rm -rf ./Col/*
rm -rf ./BW/*

ls *.png | sed -e "s/.png$//" | xargs -r -I FILE \
convert FILE.png -density 300x300 -compress jpeg \
-quality 60 ./Col/FILE.pdf
 
ls *.png | sed -e "s/.png$//" | xargs -r -I FILE \
convert FILE.png -colorspace gray -density 300x300 \
-compress jpeg -quality 60 ./BW/FILE.pdf

pdftk ./BW/*.pdf cat output BW.pdf
pdftk ./Col/*.pdf cat output Col.pdf

rm -rf ./Col/*
rm -rf ./BW/*

rmdir ./Col
rmdir ./BW

The script is run from the directory that contains the images.  It first creates two directories, one for the colour PDFs and one for the GrayScale PDFs.  Any files that may exist in these directories are deleted.  Next the images are converted to PDFs by the ImageMagick convert command.  All the png files from the directory are found via the ls command and piped to sed where the file extension is removed.  Xargs is then used to run the convert command.  Options are used to control the output, density sets the viewing DPI, compress set the compression method, and quality set the JPEG compression quality.  Colorspace is used in the second command to set the output to grayscale.

Next pdftk is used to combine the PDF's that were just created into one file.  The order of the pages in the PDF is based on the alphabetical order of the input files.

The intermediary files and folders are then deleted.  Job done, and I could leave the computer unattended for most of the time as well.

Sunday, December 4, 2011

Benefits of PNG Files

Recently while scanning some old paper work, I spotted something that beautifully illustrates one of the properties of PNG files.  After scanning a batch of images and converting them to PNG format I then ordered them by size in Windows Explorer.  A clear pattern immediately became visible by looking at the preview icons.  A cut down version of this is shown below.

File Preview Icons

A PNG file is simply an image file that uses loss less compression to reduce the file size, and the simpler the image is, the better the compression algorithm works.  By looking at the image above you can see that as the files become smaller they become simpler in structure, ie less variations in colour and less detail.  From this group of images the best compression ratio obtained was about 3 to 1, but much higher compression ratios can be obtained.

The map image below from Open Street Map for example has a compression ratio of about 20 to 1.  It is made up of only a handful of colours and has large patches of continuous colour, making it a perfect candidate for PNG compression.


Highly Compressed PNG File
This property was useful in the OpenGL map viewer software that I wrote.  The main factor limiting the update rate of map tiles was the speed at which they could be read from the disk drive.  By reading the compressed files from the disk and decompressing them in memory a speed increase was obtained.

I have to admit that I quite like using PNG files.  When compared to a BMP file they win nearly all the time, you get the added feature of an alpha (transparency) channel, and the space saving via compression that they offer.  I would only use a BMP file if I needed something that was really easy to read.  So for archiving images, PNG is the way to go.

When comparing JPEG and PNG files it really depends on the image.  If the image is photo like and has lots of detail, then JPEG is the way to go if you don't mind a slight loss of quality through compression, otherwise PNG may be a good choice.