Image Lib
Orientation Image Maps
These orientation maps are exposed through:
bundle_image2DIntensity_orientation_factory
They currently operate on intensity images and use raw Sobel derivatives internally.
using UTCGP
using ImageCore: N0f8
function orientation_vertical_step_array(n::Int = 30)
img = zeros(Float64, n, n)
img[:, fld(n, 2)+1:end] .= 1.0
return img
end
function orientation_horizontal_step_array(n::Int = 30)
img = zeros(Float64, n, n)
img[fld(n, 2)+1:end, :] .= 1.0
return img
end
function orientation_diag45_step_array(n::Int = 30)
img = zeros(Float64, n, n)
for i in 1:n, j in 1:n
img[i, j] = j >= i ? 1.0 : 0.0
end
return img
end
orientation_intensity_image(arr::AbstractMatrix{<:Real}) =
UTCGP.SImageND(UTCGP.IntensityPixel{N0f8}.(Float64.(arr)))
img = orientation_intensity_image(orientation_vertical_step_array())
grad_mag = UTCGP.bundle_image2DIntensity_orientation_factory[:grad_magnitude].fn(typeof(img))
grad_ori = UTCGP.bundle_image2DIntensity_orientation_factory[:grad_orientation].fn(typeof(img))
(typeof(grad_mag), typeof(grad_ori))(typeof(UTCGP.image2D_orientation.var"grad_magnitude_image2D_SImage2D{30, 30, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}"), typeof(UTCGP.image2D_orientation.var"grad_orientation_image2D_SImage2D{30, 30, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}"))grad_magnitude
Gradient magnitude computed from Sobel x/y derivatives.
img = asset_img
fn = UTCGP.bundle_image2DIntensity_orientation_factory[:grad_magnitude].fn(typeof(img))
fn(img)192×256 SImage2D{192, 256, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}:
IntensityPixel{N0f8}(0.031) … IntensityPixel{N0f8}(0.051)
IntensityPixel{N0f8}(0.059) IntensityPixel{N0f8}(0.039)
IntensityPixel{N0f8}(0.09) IntensityPixel{N0f8}(0.024)
IntensityPixel{N0f8}(0.129) IntensityPixel{N0f8}(0.024)
IntensityPixel{N0f8}(0.243) IntensityPixel{N0f8}(0.106)
IntensityPixel{N0f8}(0.161) … IntensityPixel{N0f8}(0.29)
IntensityPixel{N0f8}(0.027) IntensityPixel{N0f8}(0.4)
IntensityPixel{N0f8}(0.02) IntensityPixel{N0f8}(0.043)
IntensityPixel{N0f8}(0.027) IntensityPixel{N0f8}(0.008)
IntensityPixel{N0f8}(0.039) IntensityPixel{N0f8}(0.004)
⋮ ⋱ ⋮
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.043)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.012)
IntensityPixel{N0f8}(0.0) … IntensityPixel{N0f8}(0.004)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.004)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.004)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.004)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.004)
IntensityPixel{N0f8}(0.0) … IntensityPixel{N0f8}(0.008)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.008)
grad_orientation
Gradient orientation map encoded in [0, 1] over [0, π].
img = asset_img
fn = UTCGP.bundle_image2DIntensity_orientation_factory[:grad_orientation].fn(typeof(img))
fn(img)192×256 SImage2D{192, 256, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}:
IntensityPixel{N0f8}(0.604) … IntensityPixel{N0f8}(0.722)
IntensityPixel{N0f8}(0.635) IntensityPixel{N0f8}(0.475)
IntensityPixel{N0f8}(0.682) IntensityPixel{N0f8}(0.118)
IntensityPixel{N0f8}(0.643) IntensityPixel{N0f8}(0.427)
IntensityPixel{N0f8}(0.58) IntensityPixel{N0f8}(0.643)
IntensityPixel{N0f8}(0.612) … IntensityPixel{N0f8}(0.424)
IntensityPixel{N0f8}(0.275) IntensityPixel{N0f8}(0.486)
IntensityPixel{N0f8}(0.396) IntensityPixel{N0f8}(0.549)
IntensityPixel{N0f8}(0.557) IntensityPixel{N0f8}(0.353)
IntensityPixel{N0f8}(0.153) IntensityPixel{N0f8}(0.251)
⋮ ⋱ ⋮
IntensityPixel{N0f8}(0.157) IntensityPixel{N0f8}(0.549)
IntensityPixel{N0f8}(0.157) IntensityPixel{N0f8}(0.502)
IntensityPixel{N0f8}(0.157) … IntensityPixel{N0f8}(1.0)
IntensityPixel{N0f8}(0.157) IntensityPixel{N0f8}(0.604)
IntensityPixel{N0f8}(0.157) IntensityPixel{N0f8}(0.749)
IntensityPixel{N0f8}(0.157) IntensityPixel{N0f8}(0.251)
IntensityPixel{N0f8}(0.157) IntensityPixel{N0f8}(0.749)
IntensityPixel{N0f8}(0.157) … IntensityPixel{N0f8}(1.0)
IntensityPixel{N0f8}(0.157) IntensityPixel{N0f8}(1.0)
orientation_select
Keep only gradient responses whose orientation is near a target angle.
img = asset_img
fn = UTCGP.bundle_image2DIntensity_orientation_factory[:orientation_select].fn(typeof(img))
fn(img, 0.25, 0.1)192×256 SImage2D{192, 256, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}:
IntensityPixel{N0f8}(0.0) … IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) … IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.043) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.004)
⋮ ⋱ ⋮
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) … IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.004)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) … IntensityPixel{N0f8}(0.0)
IntensityPixel{N0f8}(0.0) IntensityPixel{N0f8}(0.0)
Block Pooling Functions
In this set of bundles we currently find:
avgpool_blocksmaxpool_blocksminpool_blocksavgpool_cross_blocksmaxpool_cross_blocksminpool_cross_blocks
The pooling functions are exposed through the typed image pooling bundles:
bundle_image2DIntensity_pool_factorybundle_image2DBinary_pool_factorybundle_image2DSegment_pool_factory
These functions use non-overlapping block windows scanned from left to right and top to bottom. Each block is reduced to a single value, and that value is written back over the covered block. There is no padding; the last block on the right or bottom may be partial if the image size is not divisible by k.
To obtain a callable function, first select the function from the bundle, then specialize it on the concrete image type.
using UTCGP
using ImageCore: N0f8
img = UTCGP.SImageND(UTCGP.IntensityPixel{N0f8}.(rand(4, 4)))
avg_intensity = UTCGP.bundle_image2DIntensity_pool_factory[:avgpool_blocks].fn(typeof(img))
max_intensity = UTCGP.bundle_image2DIntensity_pool_factory[:maxpool_blocks].fn(typeof(img))
(typeof(avg_intensity), typeof(max_intensity))(typeof(UTCGP.image_pool.var"avgpool_blocks_image2D_SImage2D{4, 4, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}"), typeof(UTCGP.image_pool.var"maxpool_blocks_image2D_SImage2D{4, 4, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}"))Avg Pool
UTCGP.image_pool.avgpool_blocks_image2D_factory — Function
avgpool_blocks_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create average-pooling methods specialized on the given image type.
The output preserves the original image size by average-pooling block windows and writing the pooled value back over each source block.
Intensity image, k = 2
pooled = avg_intensity(img_intensity, 2)
Intensity image, k = 10
pooled = avg_intensity(img_intensity, 10)
Binary image, > 0.3, k = 5
pooled = avg_binary(img_binary, 5)
Segmented image from fastscanning_image2D, k = 5
pooled = avg_segment(img_segment, 5)
Max Pool
UTCGP.image_pool.maxpool_blocks_image2D_factory — Function
maxpool_blocks_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create max-pooling methods specialized on the given image type.
The output preserves the original image size by max-pooling block windows and writing the pooled value back over each source block.
Intensity image, k = 2
pooled = max_intensity(img_intensity, 2)
Intensity image, k = 10
pooled = max_intensity(img_intensity, 10)
Binary image, > 0.3, k = 5
pooled = max_binary(img_binary, 5)
Segmented image from fastscanning_image2D, k = 5
pooled = max_segment(img_segment, 5)
Min Pool
UTCGP.image_pool.minpool_blocks_image2D_factory — Function
minpool_blocks_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create min-pooling methods specialized on the given image type.
The output preserves the original image size by min-pooling block windows and writing the pooled value back over each source block.
Intensity image, k = 2
pooled = min_intensity(img_intensity, 2)
Intensity image, k = 10
pooled = min_intensity(img_intensity, 10)
Binary image, > 0.3, k = 5
pooled = min_binary(img_binary, 5)
Segmented image from fastscanning_image2D, k = 5
pooled = min_segment(img_segment, 5)
Cross Pooling Functions
Avg Cross Pool
UTCGP.image_pool.avgpool_cross_blocks_image2D_factory — Function
avgpool_cross_blocks_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create cross-shaped average-pooling methods specialized on the given image type.
Within each block window, only the center row and center column are averaged. The pooled value is then written back over the full source block.
Custom 10x10 intensity image, k = 3
pooled = avg_cross_intensity(img_cross_demo, 3)
Custom 10x10 intensity image, k = 5
pooled = avg_cross_intensity(img_cross_demo, 5)
Binary image, > 0.3, k = 10
pooled = avg_cross_binary(img_binary, 10)
Segmented image from fastscanning_image2D, k = 10
pooled = avg_cross_segment(img_segment, 10)
Max Cross Pool
UTCGP.image_pool.maxpool_cross_blocks_image2D_factory — Function
maxpool_cross_blocks_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create cross-shaped max-pooling methods specialized on the given image type.
Within each block window, only the center row and center column are reduced. The pooled value is then written back over the full source block.
Custom 10x10 intensity image, k = 3
pooled = max_cross_intensity(img_cross_demo, 3)
Custom 10x10 intensity image, k = 5
pooled = max_cross_intensity(img_cross_demo, 5)
Binary image, > 0.3, k = 10
pooled = max_cross_binary(img_binary, 10)
Segmented image from fastscanning_image2D, k = 10
pooled = max_cross_segment(img_segment, 10)
Min Cross Pool
UTCGP.image_pool.minpool_cross_blocks_image2D_factory — Function
minpool_cross_blocks_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create cross-shaped min-pooling methods specialized on the given image type.
Within each block window, only the center row and center column are reduced. The pooled value is then written back over the full source block.
Custom 10x10 intensity image, k = 3
pooled = min_cross_intensity(img_cross_demo, 3)
Custom 10x10 intensity image, k = 5
pooled = min_cross_intensity(img_cross_demo, 5)
Binary image, > 0.3, k = 10
pooled = min_cross_binary(img_binary, 10)
Segmented image from fastscanning_image2D, k = 10
pooled = min_cross_segment(img_segment, 10)
Sliding Window Poolers
In this set of bundles we currently find:
meanpoolmaxpoolminpoolstdpoolmedianpooluniquecountpoolargmaxcountpoolargmincountpooliqrpool
These functions use full sliding k × k windows with no padding. Only windows that fully fit in the image are reduced, using the provided stride, and the reduced image is then resized back to the original size with nearest-neighbor sampling.
The sliding-window poolers are exposed through:
bundle_image2DIntensity_pooler_factorybundle_image2DBinary_pooler_factorybundle_image2DSegment_pooler_factory
using UTCGP
using ImageCore: N0f8
img = UTCGP.SImageND(UTCGP.IntensityPixel{N0f8}.(rand(8, 8)))
mean_intensity = UTCGP.bundle_image2DIntensity_pooler_factory[:meanpool].fn(typeof(img))
iqr_intensity = UTCGP.bundle_image2DIntensity_pooler_factory[:iqrpool].fn(typeof(img))
(typeof(mean_intensity), typeof(iqr_intensity))(typeof(UTCGP.image_pooler.var"meanpool_image2D_SImage2D{8, 8, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}"), typeof(UTCGP.image_pooler.var"iqrpool_image2D_SImage2D{8, 8, IntensityPixel{FixedPointNumbers.N0f8}, Matrix{IntensityPixel{FixedPointNumbers.N0f8}}}"))Mean Pool
UTCGP.image_pooler.meanpool_image2D_factory — Function
meanpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create mean sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:meanpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:meanpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:meanpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:meanpool](img_segment, 5, 2)
Max Pool
UTCGP.image_pooler.maxpool_image2D_factory — Function
maxpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create max sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:maxpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:maxpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:maxpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:maxpool](img_segment, 5, 2)
Min Pool
UTCGP.image_pooler.minpool_image2D_factory — Function
minpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create min sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:minpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:minpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:minpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:minpool](img_segment, 5, 2)
Std Pool
UTCGP.image_pooler.stdpool_image2D_factory — Function
stdpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create std sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:stdpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:stdpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:stdpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:stdpool](img_segment, 5, 2)
Median Pool
UTCGP.image_pooler.medianpool_image2D_factory — Function
medianpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create median sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:medianpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:medianpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:medianpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:medianpool](img_segment, 5, 2)
Unique Count Pool
UTCGP.image_pooler.uniquecountpool_image2D_factory — Function
uniquecountpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create unique-count sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:uniquecountpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:uniquecountpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:uniquecountpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:uniquecountpool](img_segment, 5, 2)
Argmax Count Pool
UTCGP.image_pooler.argmaxcountpool_image2D_factory — Function
argmaxcountpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create argmax-count sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:argmaxcountpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:argmaxcountpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:argmaxcountpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:argmaxcountpool](img_segment, 5, 2)
Argmin Count Pool
UTCGP.image_pooler.argmincountpool_image2D_factory — Function
argmincountpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create argmin-count sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:argmincountpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:argmincountpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:argmincountpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:argmincountpool](img_segment, 5, 2)
IQR Pool
UTCGP.image_pooler.iqrpool_image2D_factory — Function
iqrpool_image2D_factory(i::Type{I}) where {I<:SizedImage2D}Create interquartile-range sliding-window pooling methods specialized on the given image type.
The image is reduced over full k × k windows using the provided stride, without padding, then nearest-neighbor resized back to the original image size.
Intensity image, k = 3, stride = 1
pooled = pooler_intensity[:iqrpool](img_intensity, 3, 1)
Intensity image, k = 5, stride = 2
pooled = pooler_intensity[:iqrpool](img_intensity, 5, 2)
Binary image, k = 5, stride = 2
pooled = pooler_binary[:iqrpool](img_binary, 5, 2)
Segmented image from fastscanning_image2D, k = 5, stride = 2
pooled = pooler_segment[:iqrpool](img_segment, 5, 2)