Tag Archives: Julia

#MonthOfJulia Day 38: Imaging

Julia-Logo-Imaging

Julia has a few packages aimed at image processing. We’ll start by looking at the TestImages package, which hosts a selection of sample images, then briefly visit the ImageView package before moving onto the Images package, which implements a range of functions for image manipulation.

Test Images

The TestImages package currently provides 25 sample images, which form a convenient basis for experimentation.

julia> using TestImages
julia> readdir(joinpath(homedir(), ".julia/v0.4/TestImages/images/"))
25-element Array{ByteString,1}:
 "autumn_leaves.png" 
 "cameraman.tif"     
 "earth_apollo17.jpg"
 "fabio.png"         
 "house.tif"         
 "jetplane.tif"      
 "lake.tif"          
 "lena_color_256.tif"
 "lena_color_512.tif"
 "lena_gray_256.tif" 
 "lena_gray_512.tif" 
 "lighthouse.png"    
 "livingroom.tif"    
 "mandril_color.tif" 
 "mandril_gray.tif"  
 "mandrill.tiff"     
 "moonsurface.tiff"  
 "mountainstream.png"
 "peppers_color.tif" 
 "peppers_gray.tif"  
 "pirate.tif"        
 "toucan.png"        
 "walkbridge.tif"    
 "woman_blonde.tif"  
 "woman_darkhair.tif"

We’ll load the archetypal test image (the November 1972 Playboy centerfold of Lena Söderberg).

julia> lena = testimage("lena_color_256.tif");

Of course, now that we’ve loaded that image, we’ll want to take a look at it. To do that we’ll need the ImageView package.

julia> using ImageView
julia> view(lena)
(ImageCanvas,ImageSlice2d: zoom = Graphics.BoundingBox(0.0,256.0,0.0,256.0))

You can optionally specify the pixel spacing as a parameter to view(), which then ensures that the aspect ratio of the image is conserved on resizing. There are various other bobs and whistles associated with view(): you can click-and-drag within the image to zoom in on a particular region; various simple transformations (flipping and rotation) are possible; images can be annotated and multiple images can be arranged on a canvas for simultaneous viewing.
lena-color-512

Image Representation

Outside of the test images, an arbitrary image file can be loaded using imread() from the Images package. Naturally, there are also functions for writing images, imwrite() and writemime().

julia> using Images
julia> earth = imread(joinpath(homedir(), ".julia/v0.4/TestImages/images/earth_apollo17.jpg"))
RGB Images.Image with:
  data: 3000x3002 Array{ColorTypes.RGB{FixedPointNumbers.UfixedBase{UInt8,8}},2}
  properties:
    IMcs: sRGB
    spatialorder:  x y
    pixelspacing:  1 1

The default representation for the Image object tells us its dimensions, storage type and colour space. The spatial order indicates that the image data are stored using row major ordering. It’s also possible to specify physical units for the pixel spacing, which is particularly important if you are analysing images where absolute scale matters (for example, medical imaging). There are convenience methods for a few image properties.

julia> colorspace(earth)
"RGB"
julia> height(earth)
3002
julia> width(earth)
3000

We can examine individual pixels within the image using the indexing operator.

julia> earth[1,1]
RGB{U8}(0.047,0.008,0.0)

Each pixel is of type RGB (defined in the Colors package), which encapsulates a tuple giving the proportion of red, green and blue for that pixel. The underlying image data can also be accessed via the data() method.

earth_apollo17

The image can be split into its component colour channels using separate().

julia> earth_rgb = separate(earth)
RGB Images.Image with:
  data: 3002x3000x3 Array{FixedPointNumbers.UfixedBase{UInt8,8},3}
  properties:
    IMcs: sRGB
    colorspace: RGB
    colordim: 3
    spatialorder:  y x
    pixelspacing:  1 1

Note that the result is a three-dimensional Array. The spatial order has also changed, which means that the data are now represented using column major ordering. The data are thus effectively transposed.

Simple Image Processing

Kernel-based filtering can be applied using imfilter() or imfilter_fft(), where the latter is better suited to larger kernels. There’s a variety of helper functions for constructing kernels, like imaverage() and gaussian2d().

julia> lena_smooth = imfilter(lena, imaverage([3, 3]));
julia> lena_very_smooth = imfilter_fft(lena, ones(10, 10) / 100);
julia> lena_gauss_smooth = imfilter_gaussian(lena, [1, 2]);

The effects of the above smoothing operations can be seen below, with the original image on the left, followed by the 3-by-3 and 10-by-10 boxcar filtered versions and finally the Gaussian filtered image.

lena-smooth-panel

The imgradients() function calculates gradients across the image. You can choose from a set of methods for calculating the gradient. The morphological dilation and erosion operations are available via dilate() and erode().

julia> (lena_sobel_x, lena_sobel_y) = imgradients(lena, "sobel");
julia> lena_dilate = dilate(lena);
julia> lena_erode = erode(lena);

Below are the two components of the image gradient calculated using the Sobel operator followed by the results of dilate() and erode().

lena-sobel

lena-morphology

Other Packages

The ImageMagick package implements further imaging functionality. If, in the future, it provides an interface to the full functionality on the ImageMagick suite then it will be a truly phenomenal resource. Also worth looking at is the PiecewiseAffineTransforms package which implements a technique for warping portions of an image.

If you’d like to exercise your image processing and machine learning skills in Julia, take a look at the First Steps With Julia competition on kaggle.

The post #MonthOfJulia Day 38: Imaging appeared first on Exegetic Analytics.

#MonthOfJulia Day 37: Fourier Techniques

Julia-Logo-Fourier

The Fourier Transform is often applied to signal processing and other analyses. It allows a signal to be transformed between the time domain and the frequency domain. The efficient Fast Fourier Transform (FFT) algorithm is implemented in Julia using the FFTW library.

1D Fourier Transform

Let’s start by looking at the Fourier Transform in one dimension. We’ll create test data in the time domain using a wide rectangle function.

julia> f = [abs(x) <= 1 ? 1 : 0 for x in -5:0.1:5];
julia> length(f)
101

This is what the data look like:
signal-1D-time-domain
We’ll transform the data into the frequency domain using fft().

julia> F = fft(f);
julia> typeof(F)
Array{Complex{Float64},1}
julia> length(F)
101
julia> F = fftshift(F);

The frequency domain data are an array of Complex type with the same length as the time domain data. Since each Complex number consists of two parts (real and imaginary) it seems that we have somehow doubled the information content of our signal. This is not true because half of the frequency domain data are redundant. The fftshift() function conveniently rearranges the data in the frequency domain so that the negative frequencies are on the left.

This is what the resulting amplitude and power spectra look like:
signal-1D-amplitude-spectrum-shifted
signal-1D-power-spectrum-shifted
The analytical Fourier Transform of the rectangle function is the sinc function, which agrees well with numerical data in the plots above.

2D Fourier Transform

Let’s make things a bit more interesting: we’ll look at the analogous two-dimensional problem. But this time we’ll go in the opposite direction, starting with a two-dimensional sinc function and taking its Fourier Transform.

Building the array of sinc data is easy using a list comprehension.

julia> f = [(r = sqrt(x^2 + y^2); sinc(r)) for x in -6:0.125:6, y in -6:0.125:6];
julia> typeof(f)
Array{Float64,2}
julia> size(f)
(97,97)

It doesn’t make sense to think about a two-dimensional function in the time domain. But the Fourier Transform is quite egalitarian: it’s happy to work with a temporal signal or a spatial signal (or a signal in pretty much any other domain). So let’s suppose that our two-dimensional data are in the spatial domain. This is what it looks like:
function-2D-sinc

Generating the Fourier Transform is again a simple matter of applying fft(). No change in syntax: very nice indeed!

julia> F = fft(f);
julia> typeof(F)
Array{Complex{Float64},2}
julia> F = fftshift(F);

The power spectrum demonstrates that the result is the 2D analogue of the rectangle function.
power-2D-sinc

Higher Dimensions and Beyond

It’s just as easy to apply the FFT to higher dimensional data, although in my experience this is rarely required.

Most of the FFTW library’s functionality has been implemented in the Julia interface. For example:

  • it’s possible to generate plans for optimised FFTs using plan_fft();
  • dct() yields the Discrete Cosine Transform;
  • you can exploit conjugate symmetry in real transforms using rfft(); and
  • it’s possible to run over multiple threads using FFTW.set_num_threads().

Watch the video below in which Steve Johnson demonstrates many of the features of FFTs in Julia.

The post #MonthOfJulia Day 37: Fourier Techniques appeared first on Exegetic Analytics.

Julia, data analysis’s little sister…meets SAP HANA

By: Alvaro "Blag" Tejada Galindo

Re-posted from: http://blagrants.blogspot.com/2015/10/julia-data-analysiss-little-sistermeets.html

This post was originally posted on Julia, data analysis’s little sister…meets SAP HANA.


Julia is not that young right now…as it first appeared on 2012 -:) It is a high-level dynamic programming language designed to address the requirements of high-performance numerical and scientific computing while also being effective for general purpose programming.
Woaw! That was a big description…so why should we care? Well…maybe because Julia was designed to be the language to rule them all…a language that can be used in any given situation…and without stopping to say if that’s true or not…I must say…Julia is really cool -:)
So…no example or demonstration would be complete if we didn’t hook it up with SAP HANA, right? So…let’s go and do it -;)
First, we need to create a Calculation View and call it “FLIGHTS_BY_CARRIER”. It will be composed of two tables, SCARR and SFLIGHT.
First, we need to create a Join object and link the table by MANDT and CARRID. From here select the following fields as output MANDT, CARRID, CARRNAME, PRICE and CURRENCY.
Then create an Aggregation object selecting the fields CARRNAME, PRICE (As Aggregated Column) and CURRENCY. Filter the CURRENCY field by ‘USD’.
Then create a Projection object and select only PRICE and CARRNAME.
On the Semantics object make sure to select “CROSS CLIENT” as the Default Client.
Now, switch to the SAP HANA Development View and create a new repository. Call it “Flights”.
Create a new “XS Engine” project and call it “Flights” as well. Link it to the “Flights” repository.
Create an empty “.xsapp” file.
Create a file called “.xsaccess” with the following code.
.xsaccess
{
"exposed" : true,
"authentication" : [ { "method" : "Basic" } ]
}

Finally create a file called “flights.xsodata” with the following code

flights.xodata
service {
"Blag/FLIGHTS_BY_CARRIER.calculationview" as "FLIGHTS" keys
generate local "Id";
}

Activate your project and launch it on your browser, you should see something like this…

The SAP HANA part is done…so we can move into the Julia part…

Go into your Julia environment and install the following packages

  • HTTPClient
  • Codecs
  • LightXML

You only need to do Pkg.add(“PackageName”) for each of them.

Then create a file called Julia_HANA_XML.jl on your favorite editor and copy the following code

Julia_HANA_XML.jl
using HTTPClient.HTTPC
using Codecs
using LightXML

credentials=encode(Base64,"SYSTEM:YourPassword")
Auth = bytestring(credentials)
Auth = "Basic " * Auth

flights=HTTPC.get("http://YourServer:8000/Flights/flights.xsodata/FLIGHTS",RequestOptions(headers=[("Authorization",Auth)]))

raw_text = takebuf_string(flights.body)
xdoc = parse_string(raw_text)
xroot = root(xdoc)

entry = get_elements_by_tagname(xroot,"entry")

for flights in entry
print(content(find_element(find_element(find_element(flights,"content"),"properties"),"CARRNAME")),": ",
content(find_element(find_element(find_element(flights,"content"),"properties"),"PRICE")),"n")
end

To run this application, simply go to your Julia environment and type

Include(“Julia_HANA_XML.jl”)

If you are wondering…why didn’t I use JSON instead of XML? Well…there’s an easy explanation for that -:) Somehow…the HTTPClient package have a problem using ?$format=json so I was forced to use XML instead…
Greetings,
Blag.
Development Culture.