• For a long time I had a layout for this circuit, but could never build it, because the layout was to small to be made by tonertransfer.

    So it was the first layout I made with my new exposure unit. It’s quite small, so it fits under the LEDMatrix itself. Therefore only SMD parts are used.

    It took three trys to get it right. The first failed because the etching solution was to weak, took to long and caused heavy underetching. The second was not properly exposed.

    The third try worked perfectly. The alignment of the two layers was good and the etching took only 10 minutes.

    74HCT138

    74HCT138

    MAX6964

    MAX6964

    Soldering the SMD resistors and transistors was not very difficult using a magnifyer and tweezers.
    The 74HCT138 was more or less easy to solder, but the MAX6964 was a bit harder. (The pins have a pitch of only 0.635mm.) But with desoldering braid any superfluous solder can be removed.

    The MAX6964 is controlled via I²C. It has 2 8-bit registers which switch the 16 outputs on and off and 8 8-bit registers which controll the brightness (via PWM).

    To keep the layout easy and the number of vias low, i had to wire the pixels of the LED matrix in somewhat weird way. But this is easily compensated in software.

    The correct order for the rows is saved in a lookup-table (just an array).
    The data for one row is two bytes long. The first byte contains the data for the first four pixels. (Two bits per pixel, for red and green.) The first byte is left to right, the second byte is right to left.

    Most of the code is I²C communication and transforming pixel data to the correct format for the MAX6964.
    Layout and code can be downloaded here. Datasheet for MAX6964 here. (Maxim is very generous when it comes to shipping free samples…)

    Tags: , , , , , ,

  • I completely recoded the Image Manipulation program. It is now better structured and easier to use. Additionally I implemented the Canny Edge Detector Algorithm and some more filters. 8-bit BMP’s are still not supported, so that would be the next step.

    Binary edge image output from canny algorithm

    Binary edge image output from canny algorithm

    To test the edge detector, I used the image from the Wikipedia article on the topic, as the desired result was known for that image.

    Complete C++ code can be downloaded here (executable included).

    Executing the program without parameters displays the help.

    To perform edge detection on an image, use the following parameter sequence:

    image <input.bmp> <output.bmp> -g -f 0.8 -e -n 80 -w 80 50

    This command first converts the image to greyscale (-g), then applys gaussian blur with a standard deviation of 0.8 (-f 0.8). After that, Sobel filters for X and Y direction are convoluted with the image, which gives an edge image. Those edges are now thinned by Non-Maximum-Suppression (-n 80),  which only leaves one-pixel wide edges, which are above the given threshold. Finally the edge tracer (-w 80 50) deletes pixels not belonging to an edge, by appling hysteresis thresholding.

    Tags: , , , , , , , ,

  • When coding the gravitational simulation I found some old code from 2003 that was supposed to perform edge detection in images. Back then I did not have enough knowlegde in C++ to get it working right.
    Therefore I started with a completely new program.

    When a BMP-image is loaded, first its header is read into to structs, containing exactly the right set of variables, so that the information is easily readable.

    When needed, the pixel information is read into a dynamic twodimensional array of structs containing three unsigned 8bit integers. For this purpose I wrote a little template since C++ does not natively support dynamic memory allocation of multidimensional arrays.

    Then a number of algorithms can be performed on this array.
    Some of them are easy operations on single pixels, like inversion of colors, converting to greyscale or subtracting one picture from another.

    But the really interesting filters involve matrix convolutions. That means you take a sliding window the size of your matrix (preferrably of odd dimensions) and calculate the value for the central pixel by multiplying the surrounding pixels by the respective entries of the matrix.

    This way a lot of effects can be achieved.
    One of the more simple ones is blurring the picture. You just take the average of the pixels around the central pixel and put that value into the pixel. A better blurring can be done by weighting the entries with a gaussian function.

    The reverse effect is possible, too. A sharpening matrix subtracts the sourrounding pixels from the center.

    I implemented some matrices in the code but added a function that can dynamically read an arbitray matrix and perform a convolution on the image, so that new filters can be tested quickly.

    The program accepts as many arguments as you like and executes them in the order of entering.

    The main goal of the program is to detect edges in images.

    Gradient Estimation

    Gradient Estimation

    There are a lot of ways to filter out edges in images,  i.e. calculating the second derivative with a laplacian or estimating the gradients with gaussian and derivative-of-gaussian (DoG) convolutions.

    I am currently working on the non-maximum-suppression-algorithm which should preprocess the images for the edgedetector. The SUSAN-algorithm is already implemented and the Canny-Algorithm will follow shortly.

    The sourcecode can be found here (a compiled executable is included).

    Tags: , , , ,