class CrImage::Mask

Overview

Mask is a wrapper around BitArray, where each flag represents a boolean bit of information about a pixel from an image. This can include whether a particular pixel has a value within certain conditions, OR if that pixel should be zeroed out or not.

See #[]= methods below for examples of how to manually construct masks.

(x,y) - coordinates. Represent these positions in a Mask of size 10x10:

[
  (0,0), (0,1), (0,2), (0,3), (0,4), (0,5), (0,6), (0,7), (0,8), (0,9),
  (1,0), (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (1,8), (1,9),
  (2,0), (2,1), (2,2), (2,3), (2,4), (2,5), (2,6), (2,7), (2,8), (2,9),
  (3,0), (3,1), (3,2), (3,3), (3,4), (3,5), (3,6), (3,7), (3,8), (3,9),
  (4,0), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6), (4,7), (4,8), (4,9),
  (5,0), (5,1), (5,2), (5,3), (5,4), (5,5), (5,6), (5,7), (5,8), (5,9),
  (6,0), (6,1), (6,2), (6,3), (6,4), (6,5), (6,6), (6,7), (6,8), (6,9),
  (7,0), (7,1), (7,2), (7,3), (7,4), (7,5), (7,6), (7,7), (7,8), (7,9),
  (8,0), (8,1), (8,2), (8,3), (8,4), (8,5), (8,6), (8,7), (8,8), (8,9),
  (9,0), (9,1), (9,2), (9,3), (9,4), (9,5), (9,6), (9,7), (9,8), (9,9),
]

And every position is a Bool value.

Different ways to refer to coordinates:

mask.at(0, 0)    # => (0,0)
mask[0, 0]       # => (0,0), same as .at(0, 0)
mask[0..1, 4]    # => (4,0), (4,1)
mask[3, 3..5]    # => (3,3), (3,4), (3,5)
mask[2..3, 4..5] # => (2,4), (2,5), (3,4), (3,5)

See Operation::Crop and Operation::MaskApply for how this can be useful

Included Modules

Defined in:

cr-image/mask.cr

Constructors

Instance Method Summary

Instance methods inherited from module CrImage::Map(Bool)

[](x : Int32, y : Int32) : T
[](index : Int32) : T
[]
, []?(x : Int32, y : Int32) : T | Nil
[]?(index : Int32) : T | Nil
[]?
, height : Int32 height, shape : Tuple(Int32, Int32) shape, size : Int32 size, width : Int32 width

Constructor Detail

def self.new(width : Int32, height : Int32, initial : Bool = true) #

Construct a new Mask of width x height, preset to initial


[View source]
def self.new(width : Int32, height : Int32, int : Int) #

Construct a new Mask from an integer (useful for testing or small mask construction)


[View source]
def self.new(image : Image, initial : Bool = true) #

Construct a new Mask from the dimensions of passed in image with an initial bit


[View source]
def self.new(width : Int32, bits : BitArray) #

Construct a new Mask with a set width and bits from #bits


[View source]
def self.new(width : Int32, height : Int32, &block : Int32, Int32 -> Bool) #

Construct a new Mask of width x height using &block to determine if a bit should be true or not (passed in x and y coordinates)


[View source]
def self.new(other_bits : Array(BitArray)) #

Construct a new Mask from an array of BitArray. See #[](xs : Range, ys : Range) : Array(BitArray)

This assumes other_bits[0] corresponds to x == 0 in the mask, and the corresponding BitArray represents all bits for that row. All BitArrays must be of the same size in other_bits.


[View source]

Instance Method Detail

def ==(other : Mask) #

[View source]
def [](xstart : Int32, xcount : Int32, ystart : Int32, ycount : Int32) : Array(BitArray) #

Return an Array(BitArray) for the partial box (of partial rows and partial columns) of this mask.

Can be used to construct another mask from.


[View source]
def [](x : Int32, y : Int32) : Bool #

Return the bit at x and y


[View source]
def [](xs : Range, y : Int32) : BitArray #

Return a new BitArray corresponding to the partial row specified


[View source]
def [](x : Int32, ys : Range) : BitArray #

Return a new BitArray corresponding to the partial column specified


[View source]
def [](xs : Range, ys : Range) : Array(BitArray) #

Return an Array(BitArray) for the partial box (of partial rows and partial columns) of this mask.

Can be used to construct another mask from.


[View source]
def [](index : Int32) : Bool #

Return the bit at index


[View source]
def []=(x : Int32, y : Int32, value : Bool) : Bool #

Set the bit for coordinate x and y

mask = CrImage::Mask.new(50, 50, false)
mask[20, 20] = true
mask.to_gray.save("mask_point.jpg")
Black box with single white point at 20, 20

[View source]
def []=(xs : Range, y : Int32, value : Bool) : Bool #

Set the bits for partial row xs at column y

mask = CrImage::Mask.new(50, 50, false)
mask[20..40, 20] = true
mask.to_gray.save("mask_partial_row.jpg")
Black box with partial white horizontal line from 20, 20 to 40, 20

[View source]
def []=(x : Int32, ys : Range, value : Bool) : Bool #

Set the bits for row x and partial columns ys

mask = CrImage::Mask.new(50, 50, false)
mask[20..40, 20] = true
mask.to_gray.save("mask_partial_column.jpg")
Black box with partial white vertical line from 20, 20 to 20, 40

[View source]
def []=(xs : Range, ys : Range, value : Bool) : Bool #

Set the bits for partial rows xs and partial columns ys

mask = CrImage::Mask.new(50, 50, false)
mask[20..40, 20..40] = true
mask.to_gray.save("mask_partial_column.jpg")
Black box with smaller white box in it from 20, 20 to 40, 40

[View source]
def []?(x : Int32, y : Int32) : Bool | Nil #

[View source]
def []?(index : Int32) : Bool | Nil #

[View source]
def |(other : Mask) : Mask #

[View source]
def apply(image : Image) : Image #

Apply this mask to the provided image with Operation::MaskApply#apply


[View source]
def apply(image : Image, &block : UInt8, ChannelType, Int32, Int32 -> UInt8) : Image #

Apply this mask to the provided image with Operation::MaskApply#apply


[View source]
def at(index : Int32) : Bool #

Return the bit at index


[View source]
def bits : BitArray #

[View source]
def clone #

Create a new Mask from this one without modifying it


[View source]
def closing(*, diagonal : Bool = true) : Mask #

Closing operator


[View source]
def closing!(*, diagonal : Bool = true) : Mask #

Closing operator


[View source]
def dilate(*, diagonal : Bool = true) : Mask #

Dilation operator


[View source]
def dilate!(*, diagonal : Bool = true) : self #

Dilation operator


[View source]
def erode(*, diagonal : Bool = true) : Mask #

Erosion operator


[View source]
def erode!(*, diagonal : Bool = true) : Mask #

Erosion operator


[View source]
def height : Int32 #

[View source]
def invert #

Return a new Mask that's a copy of this one with all bits inverted.


[View source]
def invert! #

Invert all bits in this instance of Mask. Modifies self.

Black box with different regions colored white

Becomes

White box with opposite regions colored black

[View source]
def opening(*, diagonal : Bool = true) : Mask #

Opening operator


[View source]
def opening!(*, diagonal : Bool = true) : Mask #

Opening operator


[View source]
def region : Region #

Returns the bounding box of the mask where all true bits are contained. Any pixels outside of the region are false

mask = CrImage::Mask.new(50, 50, false)
mask[20..40, 20] = true
mask[20, 20..40] = true
mask.region # => Region(x: 20, y: 20, width: 20, height: 20)
Black box with white lines from 20, 20 going to 20, 40 and 40, 20

[View source]
def segments(*, diagonal : Bool = true) : Array(Mask) #

Return an array of Masks, each one corresponding to an area of contiguous true bits (identified from flood fills).

May specify diagonal: false for only 4-way (up, down, left, right) flood fill instead of default 8-way. Starting with sample mask:

mask = CrImage::Mask.new(50, 50, false)

mask[5..45, 5..45] = true
mask[15..35, 15..35] = false
mask[21..25, 21..25] = true
mask[26..30, 26..30] = true
Black box with different regions colored white

Its segments look like:

mask.segments.each_with_index do |segment, i|
  segment.to_gray.save("mask_8-way_segments_example_#{i}.jpg")
end

Yields the images:

Black box with hollow white box in it Black box with two diagonal white boxes touching in the corner

Using diagonal: false yields:

mask.segments(diagonal: false).each_with_index do |segment, i|
  segment.to_gray.save("mask_4-way_segments_example_#{i}.jpg")
end

Yields the images:

Black box with hollow white box in it Black box with small white box in upper left center Black box with small white box in lower right center

[View source]
def set(x : Int32, y : Int32, value : Bool) : Bool #

Set the bit for coordinate x and y


[View source]
def shape : Tuple(Int32, Int32) #

Returns the dimension of this mask (width x height)


[View source]
def size : Int32 #

How many bits are stored in this Mask


[View source]
def to_gray : GrayscaleImage #

Convert this Mask to a GrayscaleImage, with false bits becoming 0, and true bits becoming 255


[View source]
def width : Int32 #

[View source]