Difference between revisions of "ForkLoop Images Assignment"
m (→apply) |
|||
(34 intermediate revisions by 2 users not shown) | |||
Line 4: | Line 4: | ||
=Background= | =Background= | ||
Revisit the [[Race_Condition_Image_Batch_Assignment#Background|Image Batch Race Condition Exercise's Background]] section for information on pixels and images. | Revisit the [[Race_Condition_Image_Batch_Assignment#Background|Image Batch Race Condition Exercise's Background]] section for information on pixels and images. | ||
+ | ==HsvColor== | ||
+ | {{HsvColorWithMethodLinks}} | ||
+ | |||
+ | ==DefaultImmutableHsvImage== | ||
+ | |||
+ | ==PixelFiler== | ||
+ | {{PixelFilterWithApplyLinks}} | ||
=Code To Investigate= | =Code To Investigate= | ||
Line 10: | Line 17: | ||
==PixelFilters== | ==PixelFilters== | ||
− | + | Our Image Filter will apply a PixelFilter to every pixel in a specified image. | |
+ | |||
+ | Some example pixel filters have been provided which use named classes, anonymous classes, and lambdas: | ||
+ | |||
+ | {{CollapsibleCode|class PixelFilters |<syntaxhighlight lang="java"> | ||
+ | public class PixelFilters { | ||
private static class HueSettingPixelFilter implements PixelFilter { | private static class HueSettingPixelFilter implements PixelFilter { | ||
private final double hue; | private final double hue; | ||
Line 63: | Line 75: | ||
}; | }; | ||
} | } | ||
− | }</ | + | }</syntaxhighlight>}} |
=Code To Implement= | =Code To Implement= | ||
Line 70: | Line 82: | ||
===apply=== | ===apply=== | ||
− | {{Parallel|public | + | {{Parallel|public ImmutableHsvImage apply(ImmutableHsvImage src, PixelFilter pixelFilter)}} |
− | {{warning | When | + | |
+ | Apply the provided pixelFilter to each pixel in the src HsvImage. | ||
+ | |||
+ | Each pixel is represented by an HsvColor. | ||
+ | |||
+ | PixelFilter has one interesting method '''apply''' which takes a source HsvColor and '''returns''' a new filtered HsvColor. It will '''NOT''' modify the passed source HsvColor. It would be impossible anyway, as HsvColor is immutable. | ||
+ | |||
+ | Example use of PixelFilter apply: | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | HsvColor dstPixel = pixelFilter.apply(srcPixel); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <!-- {{warning | When saving the result of pixelFilter.apply(), always put the result in a new array. Do '''NOT''' overwrite values of the source array.}}--> | ||
+ | |||
+ | To complete this method we must return a new instance of the HsvImage class. | ||
+ | |||
+ | Nicely, HsvImage provides both: | ||
+ | * a constructor which takes an [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/current/apidocs/edu/wustl/cse231s/image/HsvImage.html#%3Cinit%3E(edu.wustl.cse231s.color.HsvColor%5B%5D%5B%5D) <nowiki>List<HsvColor[]></nowiki>] and, | ||
+ | * another constructor which takes an [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/current/apidocs/edu/wustl/cse231s/image/HsvImage.html#%3Cinit%3E(java.util.List) <nowiki>HsvColor[][]</nowiki>]. | ||
+ | |||
+ | These two constructors match up well with the two different return types of the many incantations of join_fork_loop: | ||
+ | |||
+ | * [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/spring23/apidocs/fj/FJ.html#join_fork_loop(T%5B%5D,fj.api.TaskFunction) <nowiki>List<R></nowiki>], and | ||
+ | * [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/spring23/apidocs/fj/FJ.html#join_fork_loop(java.lang.Class,T%5B%5D,fj.api.TaskFunction) <nowiki>R[]</nowiki>] | ||
+ | |||
+ | where R is the return type of the [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/current/apidocs/fj/api/TaskFunction.html <nowiki>TaskFunction<T, R></nowiki>] passed to the join_fork_loop. | ||
+ | |||
+ | What should the return type from the this TaskFunction be? | ||
+ | |||
+ | {{Requirements3|Create a task per row.|Do '''NOT''' create a task per pixel.|Use a parallel fork loop.}} | ||
+ | |||
+ | |||
+ | |||
+ | <!-- | ||
This code need only include one: ''join_fork_loop(array, (arrayValue) -> // etc... )'' and an inner for loop using pixelFilter.apply(). Each ''join_fork_loop'' iteration should return an ''HsvColor[]''. | This code need only include one: ''join_fork_loop(array, (arrayValue) -> // etc... )'' and an inner for loop using pixelFilter.apply(). Each ''join_fork_loop'' iteration should return an ''HsvColor[]''. | ||
− | + | '''Note: ''' ''join_fork_loop()'' will default to returning a ''List<HsvColor[]>'' which we don't want. To avoid this, hand ''join_fork_loop()'' the class you'll return: e.g. | |
+ | |||
+ | <nowiki>HsvColor[][] destination = join_fork_loop(HsvColor[].class, array, (arrayValue) -> { | ||
+ | // code returning HsvColor[]'s | ||
+ | });</nowiki> | ||
+ | As opposed to: | ||
+ | <nowiki>List<HsvColor[]> destination = join_fork_loop(array, (arrayValue) -> { | ||
+ | // code returning HsvColor[]'s | ||
+ | });</nowiki> | ||
+ | Finish out the method by returning a ''new DefaultHsvImage()'' which accepts a HsvColor[][] in its constructor. | ||
+ | --> | ||
=Visualization= | =Visualization= |
Latest revision as of 20:49, 9 September 2024
Contents
Motivation
We gain experience using a parallel fork loop. Image processing often presents the opportunity for a lot of parallelism. Here we will operate on a single image, making a parallel task for each row.
Background
Revisit the Image Batch Race Condition Exercise's Background section for information on pixels and images.
HsvColor
class HsvColor
DefaultImmutableHsvImage
PixelFiler
interface PixelFilter extends UnaryOperator<HsvColor>
Code To Investigate
Image Batch Race Condition Exercise
Image Batch Race Condition Code To Investigate
PixelFilters
Our Image Filter will apply a PixelFilter to every pixel in a specified image.
Some example pixel filters have been provided which use named classes, anonymous classes, and lambdas:
class PixelFilters |
---|
public class PixelFilters {
private static class HueSettingPixelFilter implements PixelFilter {
private final double hue;
public HueSettingPixelFilter(double hue) {
this.hue = hue;
}
@Override
public HsvColor apply(HsvColor src) {
double saturation = src.saturation();
double value = src.value();
return new HsvColor(hue, saturation, value);
}
}
public static PixelFilter hueSettingPixelFilterOf(double hue) {
// return new instance of named class HueSettingPixelFilter
return new HueSettingPixelFilter(hue);
}
public static PixelFilter hueAdjustingPixelFilterOf(double deltaHue) {
// return new instance of anonymous class
return new PixelFilter() {
@Override
public HsvColor apply(HsvColor src) {
double hue = src.hue();
double saturation = src.saturation();
double value = src.value();
return new HsvColor(hue + deltaHue, saturation, value);
}
};
}
public static PixelFilter saturationAdjustingPixelFilterOf(double deltaSaturation) {
// return anonymous function (also known as a lambda) with parameter type
return (HsvColor src) -> {
double hue = src.hue();
double saturation = src.saturation();
double value = src.value();
return new HsvColor(hue, saturation + deltaSaturation, value);
};
}
public static PixelFilter valueAdjustingPixelFilterOf(double deltaValue) {
// return anonymous function (also known as a lambda) without parameter type
return src -> {
double hue = src.hue();
double saturation = src.saturation();
double value = src.value();
return new HsvColor(hue, saturation, value + deltaValue);
};
}
}
|
Code To Implement
ParallelTaskPerRowImageFilter
class: | ParallelTaskPerRowImageFilter.java | |
methods: | apply | |
package: | imagefilter.exercise | |
source folder: | student/src/main/java |
apply
method: public ImmutableHsvImage apply(ImmutableHsvImage src, PixelFilter pixelFilter)
(parallel implementation required)
Apply the provided pixelFilter to each pixel in the src HsvImage.
Each pixel is represented by an HsvColor.
PixelFilter has one interesting method apply which takes a source HsvColor and returns a new filtered HsvColor. It will NOT modify the passed source HsvColor. It would be impossible anyway, as HsvColor is immutable.
Example use of PixelFilter apply:
HsvColor dstPixel = pixelFilter.apply(srcPixel);
To complete this method we must return a new instance of the HsvImage class.
Nicely, HsvImage provides both:
- a constructor which takes an List<HsvColor[]> and,
- another constructor which takes an HsvColor[][].
These two constructors match up well with the two different return types of the many incantations of join_fork_loop:
where R is the return type of the TaskFunction<T, R> passed to the join_fork_loop.
What should the return type from the this TaskFunction be?
Requirements: |
Create a task per row. |
Do NOT create a task per pixel. |
Use a parallel fork loop. |
Visualization
class: | ImageFilterApp.java | VIZ |
package: | imagefilter.viz | |
source folder: | student/src/main/java |
Testing Your Solution
class: | __ParallelTaskPerRowImageFilterTestSuite.java | |
package: | imagefilter.exercise | |
source folder: | testing/src/test/java |
Pledge, Acknowledgments, Citations
file: | exercise-fork-loop-images-pledge-acknowledgments-citations.txt |
More info about the Honor Pledge