Speeding up blob analysis - python

I am developing an OpenCV application under Python. Several of the processing steps involve blob analysis (connected components labeling) after binarization. All is fine, except sometimes, when image noise is present, the number of blobs explodes and so does the processing time (say 1 second instead of 10 ms).
For the moment I am using the function connectedComponentsWithStats. I actually need the areas and centroids of the blobs.
Do you know of an alternative function which remains fast when there are many blobs, or which does a pre-filtering on size, or a way to apply a size filer on the binary image ?

Related

How do I find a dataset with a ground truth(perfect image) to compare a hole filling appraoch?

I am using python and OpenCV to perform spatial and temporal denoising on rgb-d images. However, until now I was using data physically captured using Kinect in my lab. But I realised, after hole filling(spatial denoising) I will require a pixelwise perfect depth image meaning, without holes/temporal noise (or groundtruth) to compare the hole filled output. So that I can conclude the efficiency of my approach. I have tried searching for online databases such as KITTY, Middlebury, TUM and Darmstadt dataset but none of them have a perfect .png image I can use as my groundtruth. Is there any such dataset available that could be useful for my application or will I have to create a groundtruth myself by using any tools/plugins to create artificial depth images from computer generated 3D scenes or reproduce depth noise?

Apply image smoothing and edge detection algorithms on a 2.4 GB GeoTIFF image

So I have over 150,000 huge GeoTIFF images (each 2.4 GB) which I need to run image smoothing and edge detection (LoG Filter) on, to get a sharpened image. I read the image using Gdal, smoothed it, subsampled it, created a high-pass filter (level 5) and reconstructed the image.
This works fine for a normal .jpg file.
But I'm not able to accomplish this for a huge TIFF file becaus I keep running into memory errors even with a 32 GB RAM 8 core processor and 4 TB disk space.
What is the best way to do heavy weight image processing / image segmentation on a Python 3.6 Ubuntu 18 LTS?
pyvips can process huge images quickly and in little memory. It's LGPL, runs on Linux, macOS and Windows, and works on every version of Python. Most linuxes (including Ubuntu) have it in the package manager.
It's a demand-driven, streaming image processing library. Instead of processing images in single huge lumps, it constructs a network of image processing operators behind your back and pixels are pulled through your computer's memory in small regions by the need to create the output.
For example, I can run this program:
import sys
import pyvips
# access='sequential' puts pyvips into streaming mode for this image
im = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
im = im.crop(100, 100, im.width - 200, im.height - 200)
# 10% shrink, lanczos3 (by default)
im = im.resize(0.9)
mask = pyvips.Image.new_from_array([[-1, -1, -1],
[-1, 16, -1],
[-1, -1, -1]], scale=8)
# integer convolution ... you can use large float masks too, canny,
# sobel, etc. etc.
im = im.conv(mask, precision='integer')
im.write_to_file(sys.argv[2])
On a 40k x 30k pixel GeoTIFF image:
$ vipsheader SAV_X5S_transparent_mosaic_group1.tif
SAV_X5S_transparent_mosaic_group1.tif: 42106x29852 uchar, 4 bands, srgb, tiffload
On this 2015 laptop runs like this:
$ /usr/bin/time -f %M:%e python3 bench.py SAV_X5S_transparent_mosaic_group1.tif x.tif
257012:101.43
ie. 260mb of ram, 101s of elapsed time. It should be quite a bit quicker on your large machine.
One issue you might have is with the GeoTIFF tags: they won't be preserved by pyvips. Perhaps you won't need them in later processing.
Typically, such large images are processed tile-wise. The idea is to divide the image up into tiles, read each one in independently, with enough "overlap" to account for the filtering applied, process it and write it to file.
The TIFF standard knows the "tiled" format (I believe GeoTIFF files are typically stored in a tiled format). This format is explicitly designed to make it easy to read in a small window of the image without having to piece together bits and pieces from all over the file. Each tile in the TIFF file can be indexed by location, and is encoded and compressed independently, making it easy to read in and write out one tile at a time.
The overlap you need depends on the filtering applied. If you apply, say, a Laplace of Gaussian filter with a 9x9 window (reaches 4 pixels past the central pixel), and then overlap needs to be only 4 pixels. If you chain filters, you typically want to add the reach of each filter to obtain a total overlap value.
Next, divide the image into some multiple of the tile size in the TIFF file. Say the file has tiles of 512x512 pixels. You can choose to process 8 tiles at once, a region of 2048x2048 pixels.
Now loop over the image in steps of 2048 in each dimension. Read in the 8 tiles, and include neighboring tiles, which you will crop so that you get square images of 2048+2*4 pixels to a side. Process the sub-image, remove the overlap region, and write the rest to the corresponding tiles in the output TIFF file. The output TIFF file should be set up in the same way as the input TIFF file.
I am sure there is software out there that automates this process, but I don't know of any in Python. If you implement this yourself, you will need to learn how to read and write individual tiles in the TIFF file. One option is pylibtiff.

Python Data Matrix Detection

By using open source library, pylibdmtx is able to detect data matrix barcode inside an image. The processing speed slower when the barcode just a small portion in a large image. It take few argument to shrink and detected the barcode
Here is a part of coding in the library
with libdmtx_decoder(img, shrink) as decoder:
properties = [
(DmtxProperty.DmtxPropScanGap, gap_size),
(DmtxProperty.DmtxPropSymbolSize, shape),
(DmtxProperty.DmtxPropSquareDevn, deviation),
(DmtxProperty.DmtxPropEdgeThresh, threshold),
(DmtxProperty.DmtxPropEdgeMin, min_edge),
(DmtxProperty.DmtxPropEdgeMax, max_edge)
]
My question is, is there any other library to use beside pylibdmtx ? Or any suggestion to increase the processing speed without affect the accuracy. By the way pylibdmtx is updated on 18/1/2017, it is a maintained library
An option is to pre-locate the code by image filtering.
A Data Matrix has a high contrast (in theory) and a given cell size. If you shring the image so that cells become one or two pixels large, the Data Matrix will stand-out as a highly textured area, and the gradient will strongly respond.
I am also using this library for decoding data matrix and i found something about these arguments that timeout is int value in milliseconds which is really helping for quickly decoding and gap_size is no of pixels between tow data matrix used when you have more than one data matrix in sequence to decode with equal gap. with threshold you can directly give threshold value between 0-100 to this function without using open-CV functions and max count is no of data matrix to be decode in one image and shape is data_matrix size i. for 1010 it is 0, 1212 it is 1 and so on.
by using all these together we can have quick and effective decoding of data matrix.

Fast access of Large Image Dataset

I have multiple large image data set that contains north of 500 images that are 1080p or 4K. I need to process two consecutive images at a time (so pair wise) and the processing needs to be done on individual pixels.
I have tried using python (PIL) but loading the image into memory and then accessing the pixel values takes a lot of time.
What is the fastest way to load these images into memory and run some algorithm's on them?
PS: A solution in any language would do.
Thanks

What is the lowest resolution or fastest rescaling algorithm for Opencv images

I'm looking for a image format with a very low resolution (e.g. 0-25 possible intensity levels) in Opencv for my real-time image processing
The problem
I'm developing a machine learning algorithm based on decision trees. This algorithm gets as input a dataset with multiple features where each feature can have a value from 0 to max. intensity level. As I am currently working with 8-bit Opencv formats this results in a range from 0 - 255 different levels. This resolution is way to fine due to I'm working with a very sparse dataset (i.e. it ends up in let's say 70% undefined cases). But if i rescale these values by e.g. 10 (so the range 0-25) the predictions are still alright and the number of undefined cases are going towards 0.
My current solution
I manually downscale every pixel with the help of loops by a particular value for the algorithm and afterwards upscale it again so it can be shown to the user. This takes too much time.
Would be nice if Opencv would provide a format with even smaller resolution, so I could work with these images right away and skip this preprocessing. If 8-bit greyscale images are already the smallest format, what is the fastest algorithm to easily rescale those ?

Categories