Skip to content

Different variants of processing images in java using multithreading.

Notifications You must be signed in to change notification settings

enricoDec/Parallel-Image-processing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Parallel-Image-processing

The aim of this project is to convert PNG or JPG files from the RGB format into three other output formats using parallelization:

  1. A grayscale image
  2. A histogram
  3. An image with altered brightness

Originally, the project was intended to compare the performance differences between these conversions with and without the use of OpenMP. However, after consultation with Professor Dr. Nikita Kovalenko, it was agreed to solve the task using the Java internal Runnable interface. The complete implementation can be found on GitHub.

Two variants, a Blocking and a Non-Blocking version, were utilized for the implementation, and both will be compared later. The image file is read from shared memory, which is a thread-safe approach, eliminating the need for additional synchronization. Each thread processes its own row of pixels. In the Blocking version, shared memory is used, and individual threads write their results directly and in a synchronized manner. This prevents race conditions and reduces overhead when retrieving results after execution. However, this approach also leads to increased thread runtime because all threads can calculate in parallel but cannot write simultaneously. In the Non-Blocking version, each thread has its own memory for calculated values, avoiding race conditions as well. Once all threads have completed the calculations, the results are merged. However, additional time is required for result consolidation. The entire parallelization and synchronization are facilitated by the Java "Runnable" interface, and the code to be executed by the threads is simply written within the run method.

Documentation (German)

Bericht
Pres Folien

ToC

  1. Converting an Image to Greyscale
  2. Changing Image Brightness
  3. Creating Image RGB Histogram
  4. Project
  5. Benchmarks
  6. Logger

Converting an Image to Greyscale

Example:

ParallelImageProcessor processor = new GreyScaleProcessor(2);
ProcessorResult result = processor.processImage(file);
BufferedImage image = result.getImage();

Short version:

ParallelImageProcessor processor = new GreyScaleProcessor(2);
BufferedImage image = processor.processImage(file).getImage();
Original Image Original Image in Greyscale
Original Image Original Image in Greyscale

Changing Image Brightness

Example:

ParallelImageProcessor processor = new BrightnessProcessor(2, 2.0);
ProcessorResult result = processor.processImage(file);
BufferedImage image = result.getImage();
Original Image Original Image with increased brightness
Original Image Original Image with increased brightness

Creating Image RGB Histogram

Example:

ParallelImageProcessor processor = new HistogramProcessor(2);
ProcessorResult result = processor.processImage(file);
Histogram histogram = result.getHistogram();
histogram.saveHistogram(outputFile);
Original Image RGB Histogram of Original Image
Original Image RGB Histogram of Original Image

The Histogram can also be shown in an interactive Interface:

ParallelImageProcessor processor = new HistogramProcessor(threadPoolSize);
Histogram histogram = processor.processImage(file).getHistogram();
histogram.showHistogram();

Project

The main Goal of this Project was to test different variants of processing images in java with Threads. Mainly two different Variant ‘Blocking’ and ‘Non-Blocking’ have been developed for each Task (RGB->Greyscale, RGB->Brightness and RGB->Histogram). The different Task and Variant can be seen in the class UML.
Both ‘Blocking’ and ‘Non-Blocking’ Task-variants share the Image file in the shared-memory to read data from it. This is not synchronized as it is thread-safe. The Non-Blocking variants uses non-shared-memory between Threads to store the results and merges them all together after all Threads have stopped. This gives the chance for each Threads to run in Parallel (still determined by OS). The Blocking variant uses shared-memory to write directly the result (synchronized). This results to a higher thread run time but less overhead to retrieve the results after execution.

Class UML

Class UML

Benchmarks

Processor: 1,4 GHz Quad-Core Intel Core i5
Memory: 8 GB 2133 MHz LPDDR3
OS: macOS Ventura Version 13.0.1 (22A400)

For each Task and Variant the Task was executed 1000 times and the execution time was recorded. The benchmark results can be seen under /src/main/resources/testResults, they include the raw results as csv and some graphics. The Tests can be found under /src/test/java.

Greyscale

Blocking Non-Blocking
Blocking Non-Blocking
Blocking Non-Blocking

Brightness

Blocking Non-Blocking
Blocking Non-Blocking
Blocking Non-Blocking

Histogram

Blocking Non-Blocking
Blocking Non-Blocking
Blocking Non-Blocking

Logger

private static final Logger logger = Logger.getInstance();

logger.start(Logger.TYPE.DEBUG, null);
logger.close();

About

Different variants of processing images in java using multithreading.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages