patch-image: Compose a big image from overlapping parts

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.



Compose a collage from overlapping image parts. In contrast to Hugin, this is not intended for creating panoramas from multiple photographies, but instead is specialised to creating highly accurate reconstructions of flat but big image sources, like record covers, posters or newspapers. It solves the problem that your scanner may be too small to capture a certain image as a whole.

There are two versions of the program:

Both of them have their individual installation difficulties.


[Skip to ReadMe]


Versions0.1,,, 0.2, 0.3,, 0.3.1, 0.3.2, 0.3.2,
Dependenciesaccelerate (==1.1.*), accelerate-arithmetic (==1.0.*), accelerate-cufft (==1.0.*), accelerate-fourier (==1.0.*), accelerate-io (==1.0.*), accelerate-llvm-ptx (==1.1.*), accelerate-utility (==1.0.*), array (>=0.4 && <0.6), base (==4.*), bool8 (==0.0.*), bytestring (>=0.9.2 && <0.11), Cabal (>=1.18 && <3), carray (>=0.1.5 && <0.2), cassava (>=0.4.5 && <0.5.2), containers (>=0.4.2 && <0.7), dsp (>=0.2.4 && <0.3), enumset (>=0.0.4 && <0.1), explicit-exception (>=0.1.7 && <0.2), fft (>=0.1.7 && <0.2), filepath (>=1.3 && <1.5), gnuplot (==0.5.*), JuicyPixels (>=2.0 && <3.3), knead (==0.3.*), llvm-extra (==0.8.*), llvm-tf (==3.1.*), non-empty (>=0.2 && <0.4), pqueue (>=1.2 && <1.5), prelude-compat (==0.0.*), semigroups (>=0.1 && <1.0), storable-complex (>=0.2.2 && <0.3), storable-tuple (>=0.0.3 && <0.1), tfp (==1.0.*), unordered-containers (>=0.2.5 && <0.2.10), utility-ht (>=0.0.13 && <0.1), vector (>=0.10 && <0.13) [details]
AuthorHenning Thielemann <>
MaintainerHenning Thielemann <>
Home page
Source repositorythis: darcs clone --tag 0.3.2
head: darcs clone
Executablespatch-image-draft, patch-image-cuda, patch-image-llvm
UploadedSun Oct 7 08:24:34 UTC 2018 by HenningThielemann



Build program version base on knead


Build program version base on accelerate-cuda


Build draft program


Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info


Maintainers' corner

For package maintainers and hackage trustees

Readme for patch-image-0.3.2

[back to package description]

Automatic mode

This is the workflow: Scan parts of an image that considerably overlap. They must all be approximately oriented correctly. The program uses the overlapping areas for reconstruction of the layout of the parts. If all parts are in the directory part then in the best case you can simply run:

patch-image --output=collage.jpeg part/*.jpeg

If you get blurred areas, you might enable an additional rotation correction:

patch-image --finetune-rotate --output=collage.jpeg part/*.jpeg

It follows an overview of how the program works. It implies some things you should care about when using the program.

The program runs three phases:

The first phase orientates each part such that horizontal structures become perfectly aligned. Only the brightness channel of the image is analysed. Horizontal structures can be text or the border of the image. This also means that you should orientate the parts horizontally, not vertically. I also recommend not to mix horizontal and vertical scanned parts since the horizontal and vertical resolution of your scanner might differ slightly. However, it should be fine to rotate the image source by 180° and rotate it back digitally, before feeding it to the patch-image program.

1st Phase

Options for the first phase:

2nd Phase

In the second phase the program looks for overlapping parts between all pairs of images. For every pair it computes a convolution via a Fourier transform. Only the brightness channel of the image is analysed.

Since in the first phase every image part is oriented individually, it may happen that the part orientations don't match. This would result in blurred areas in the final collage. In order to correct this, you can run phase two in an extended mode, that also re-evaluates the part orientations. The orientation of the composed image is then determined by the estimated orientation of the first image.


3rd Phase

The third phase composes a big image from the parts. These parts are weighted such that the part boundaries cannot be seen anymore and differences in brightness are faded into another. The downside is that the superposition may lead to blur.


Our LLVM implementation provides an additional way to assemble the image parts. The already known weighting approach tries to blend across all the overlapping area. This can equalize differences in brightness. The downside is that imperfectly matching image parts lead to blurred content in the overlapping area. An alternative algorithm tries to make the overlapping as small as possible and additionally performs blending where it hurts least. More precisely, parts are blended where they differ least. However, if the brightness of the image parts differ then the blending boundaries may become visible.


General options:

Semi-Automatic mode: inspection and correction

If the program does not work correctly on a particular set of images or if you want to archive what it has done, then the following options may help you.

Trouble shooting

Unrelated images are recognized as overlapping or vice versa

If the program misses related image pairs or recognizes unrelated images as overlapping, you may first watch the overlap differences the program prints. You may then adapt the threshold via the --maximum-difference option.

The total image might contain repetitive elements that make unrelated image parts look like they overlap. So, if there is no clear threshold or you find the above procedure inappropriate, you may alternatively let the program emit a relation.csv file using the --output-state option. You can then edit relation.csv file and re-run the program with the option --relations=relation.csv.