From 532b2c98df79c715c00b723805ce0fb2d3f11d9d Mon Sep 17 00:00:00 2001 From: Dmitry Bushev Date: Thu, 18 Mar 2021 11:32:22 +0300 Subject: [PATCH] docs: std-lib --- distribution/std-lib/Standard/src/Image.enso | 5 ++ .../std-lib/Standard/src/Image/Codecs.enso | 20 ++++++ .../Standard/src/Image/Codecs/Internal.enso | 6 ++ .../Standard/src/Image/Data/Image.enso | 52 +++++++++++++- .../src/Image/Data/Image/Internal.enso | 2 - .../Standard/src/Image/Data/Matrix.enso | 70 ++++++++++++++++++- .../src/Image/Data/Matrix/Internal.enso | 6 -- 7 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 distribution/std-lib/Standard/src/Image.enso diff --git a/distribution/std-lib/Standard/src/Image.enso b/distribution/std-lib/Standard/src/Image.enso new file mode 100644 index 0000000000000..966c758e2bdc4 --- /dev/null +++ b/distribution/std-lib/Standard/src/Image.enso @@ -0,0 +1,5 @@ +from Standard.Base import all + +import Standard.Image.Codecs + +from Standard.Image.Codecs export read, write diff --git a/distribution/std-lib/Standard/src/Image/Codecs.enso b/distribution/std-lib/Standard/src/Image/Codecs.enso index 7566999ff3d5c..34a9b16ec5adf 100644 --- a/distribution/std-lib/Standard/src/Image/Codecs.enso +++ b/distribution/std-lib/Standard/src/Image/Codecs.enso @@ -43,6 +43,17 @@ type Write_Flag compression is used. type Write_Webp_Quality value +## Read the image from a file. + + The functon reads images in BGR format, or BGRA if the `Read_Alpha_Channel` flag is specified. + + > Example + Read the image. + Codecs.read "image.png" + Read the image with alpha channel. + Codecs.read "image.png" Codecs.Read_Alpha_Channel + Read the image and convert it to grayscale. + Codecs.read "image.png" Codecs.Read_Grayscale read : (Text | File) -> (Read_Flag | Vector) -> Image ! File.Io_Error read location flags=[] = path = case location of @@ -58,6 +69,15 @@ read location flags=[] = Polyglot_Error _ -> Error.throw (File.Io_Error ('Failed to read ' + path)) err -> Panic.throw err +## Write the image to a file. + + > Example + Write the image with applying png compression. + Codecs.write image + Write the image with applying png compression. + Codecs.write image (Codecs.Write_Png_Compression 9) + Write the image with applying several flags. + Codecs.write image [Codecs.Write_Jpeg_Quality 40, Codecs.Write_Jpeg_Progressive] write : (Text | File) -> Image -> (Write_Flag | Vector) -> Nothing ! File.Io_Error write location image flags=[] = path = case location of diff --git a/distribution/std-lib/Standard/src/Image/Codecs/Internal.enso b/distribution/std-lib/Standard/src/Image/Codecs/Internal.enso index 51916472a063b..f3ed2049e7c15 100644 --- a/distribution/std-lib/Standard/src/Image/Codecs/Internal.enso +++ b/distribution/std-lib/Standard/src/Image/Codecs/Internal.enso @@ -5,12 +5,16 @@ polyglot java import org.opencv.core.MatOfInt polyglot java import org.opencv.imgcodecs.Imgcodecs ## PRIVATE + + Convert read flag to OpenCV. read_flag_to_integer flag = case flag of Codecs.Read_Alpha_Channel -> Imgcodecs.IMREAD_UNCHANGED Codecs.Read_Grayscale -> Imgcodecs.IMREAD_GRAYSCALE Codecs.Read_Gdal -> Imgcodecs.IMREAD_LOAD_GDAL ## PRIVATE + + Convert write flag to OpenCV. write_flag_to_vector flag = case flag of Codecs.Write_Jpeg_Quality value -> [Imgcodecs.IMWRITE_JPEG_QUALITY, value] Codecs.Write_Jpeg_Progressive -> [Imgcodecs.IMWRITE_JPEG_PROGRESSIVE, 1] @@ -21,5 +25,7 @@ write_flag_to_vector flag = case flag of Codecs.Write_Webp_Quality value -> [Imgcodecs.IMWRITE_WEBP_QUALITY, value] ## PRIVATE + + Create an OpenCV matrix holding the flag values. write_flags_to_mat flags = MatOfInt.new (flags.flat_map here.write_flag_to_vector . to_array) diff --git a/distribution/std-lib/Standard/src/Image/Data/Image.enso b/distribution/std-lib/Standard/src/Image/Data/Image.enso index ef5e5dba2155b..0637ed35438f1 100644 --- a/distribution/std-lib/Standard/src/Image/Data/Image.enso +++ b/distribution/std-lib/Standard/src/Image/Data/Image.enso @@ -7,20 +7,26 @@ polyglot java import org.enso.image.data.Image as Java_Image type Image + ## The image data type. + + The image is represented with a matrix of rows x columns. Each + pixel is represented with a vector of 1 to 4 values (channels). + Pixel values are normalized in a range [0.0 .. 1.0]. type Image opencv_mat + ## Return the number of image rows. rows : Integer rows = this.opencv_mat.rows + ## Return the number of image columns. columns : Integer columns = this.opencv_mat.cols + ## Return the number of image channels. channels : Integer channels = this.opencv_mat.channels - copy : Image - copy = Image this.opencv_mat.clone - + ## Get the pixel value indexed by row and column. get : Integer -> Integer -> Vector ! Matrix.Index_Out_Of_Bounds_Error get row column = if (row < 0) || (row >= this.rows) then Error.throw (Matrix.Index_Out_Of_Bounds_Error row) else @@ -29,37 +35,77 @@ type Image Vector.Vector arr ## Calculates the per-element sum of an image and a scalar. + + > Example + Add the constant to an image. Operation will add 0.1 to each channel of the image. + image + 0.1 + Add 0.1 to the first channel of the image. + image + [0.1] + image + [0.1, 0, 0] + : (Number | Vector) -> Image + value = Internal.core_op this.opencv_mat value (Java_Image.add _ _ _) ## Calculates the per-element difference between an image and a scalar. + + > Example + Subtract 0.5 from each channel of the image. + image - 0.5 + Subtract 0.5 from second channel of the image. + image - [0, 0.5] == image - [0, 0.5, 0, 0] - : (Number | Vector) -> Image - value = Internal.core_op this.opencv_mat value (Java_Image.subtract _ _ _) ## Calculates the per-element product of an image and a scalar. + + > Example + Multiply each channel of the image by 2. + image * 2 + Multiply first channel of the image by 2, and second channel by 4. + image * [2, 4, 1, 1] + Multiply first channel of the image by 2, and zero the rest of the channels. + image * [2] * : (Number | Vector) -> Image * value = Internal.core_op this.opencv_mat value (Java_Image.multiply _ _ _) ## Performs per-element division of an image and a scalar. + + > Example + Divide each channel of the image by 2. + image / 2 + Divide first channel of the image by 2, and second channel by 4. + image / [2, 4, 1, 1] + Divide first channel of the image by 2, and zero the rest of the channels. + image / [2] / : (Number | Vector) -> Image / value = Internal.core_op this.opencv_mat value (Java_Image.divide _ _ _) + ## Check equality of two images. == : Image -> Boolean == that = Java_Image.is_equals this.opencv_mat that.opencv_mat + ## Convert the image to a vector. to_vector : Vector to_vector = arr = Java_Image.to_vector this.opencv_mat Vector.Vector arr + ## Convert the image to Json. to_json : Json to_json = base64 = Java_Image.to_base64 this.opencv_mat Json.from_pairs [["mediaType", "image/png"], ["base64", base64]] + ## Create a histogram for the specified channel. histogram : Integer -> Histogram histogram channel = Histogram.calculate this channel +## Create an image from the array of values. + + The function expects the array of normalized values in a range of [0.0 .. 1.1]. + + > Example + Create an image from the vector. + Image.from_vector [0, 0, 0, 0, 0, 0] rows=2 channels=1 from_vector : Vector -> Integer -> Integer -> Image from_vector data rows=1 channels=1 = Image (Java_Image.from_vector data.to_array rows channels) diff --git a/distribution/std-lib/Standard/src/Image/Data/Image/Internal.enso b/distribution/std-lib/Standard/src/Image/Data/Image/Internal.enso index 3598b93897aae..4032b94e61cd4 100644 --- a/distribution/std-lib/Standard/src/Image/Data/Image/Internal.enso +++ b/distribution/std-lib/Standard/src/Image/Data/Image/Internal.enso @@ -12,8 +12,6 @@ core_op mat value function = scalar = case value of Vector.Vector arr -> Scalar.new arr - Matrix.Matrix m -> - m _ -> Scalar.all value function mat scalar result diff --git a/distribution/std-lib/Standard/src/Image/Data/Matrix.enso b/distribution/std-lib/Standard/src/Image/Data/Matrix.enso index 40b38c0f9bdd3..d192385a1ef05 100644 --- a/distribution/std-lib/Standard/src/Image/Data/Matrix.enso +++ b/distribution/std-lib/Standard/src/Image/Data/Matrix.enso @@ -9,20 +9,26 @@ type Index_Out_Of_Bounds_Error index type Matrix + ## The matrix data type. + + Each value of the matrix is represented with an array of + channels. In contrast to an Image data type, Matrix values are + not normalized. type Matrix opencv_mat + ## Return the number of matrix rows. rows : Integer rows = this.opencv_mat.rows + ## Return the number of matrix columns. columns : Integer columns = this.opencv_mat.cols + ## Return the number of matrix channels. channels : Integer channels = this.opencv_mat.channels - copy : Matrix - copy = Matrix this.opencv_mat.clone - + ## Get the matrix value at specified row and column. get : Integer -> Integer -> Vector ! Index_Out_Of_Bounds_Error get row column = if (row < 0) || (row >= this.rows) then Error.throw (Index_Out_Of_Bounds_Error row) else @@ -30,6 +36,11 @@ type Matrix arr = Java_Matrix.get this.opencv_mat row column Vector.Vector arr + ## Reshape the matrix specifying new number of rows and channels. + + > Example + Reshape the matrix to a new shape of 3 rows and 1 column, with 1 channel. + Matrix.from_vector [0, 0, 0] . reshape rows=3 channels=1 reshape : Integer -> Integer -> Matrix reshape rows channels=Nothing = case channels of @@ -37,21 +48,54 @@ type Matrix _ -> Matrix (this.opencv_mat.reshape channels rows) ## Calculates the per-element sum of two matrices or a matrix and a scalar. + + > Example + Add 1 to each channel of the matrix. + m + 1 + Add 100 to the first channel of the matrix. + m + [100] == m + [100, 0, 0] + : (Number | Matrix | Vector) -> Matrix + value = Internal.core_op this.opencv_mat value (Java_Matrix.add _ _ _) ## Calculates the per-element difference of two matrices or of a matrix and a scalar. + + > Example + Subtract 10 from each channel of the matrix. + m - 10 + Subtract 2 from second channel of the matrix. + m - [0, 2] == m - [0, 2, 0, 0] + Subtract two matrices: + m - m - : (Number | Matrix | Vector) -> Matrix - value = Internal.core_op this.opencv_mat value (Java_Matrix.subtract _ _ _) ## Calculates the per-element product of two matrices or a matrix and a scalar. + + > Example + Multiply each channel of the matrix by 2. + m * 2 + Multiply first channel of the matrix by 2, and second channel by 4. + m * [2, 4, 1, 1] + Multiply first channel of the matrix by 2, and zero the rest of the channels. + m * [2] + Multiply two matrices. + m * m * : (Number | Matrix | Vector) -> Matrix * value = Internal.core_op this.opencv_mat value (Java_Matrix.multiply _ _ _) ## Performs per-element division of two matrices or a matrix and a scalar. + + > Example + Divide each channel of the matrix by 2. + m / 2 + Divide first channel of the matrix by 2, and second channel by 4. + m / [2, 4, 1, 1] + Divide two matrices. + m / m / : (Number | Matrix | Vector) -> Matrix / value = Internal.core_op this.opencv_mat value (Java_Matrix.divide _ _ _) + ## Check the equality of two matrices. == : Matrix -> Boolean == that = Java_Matrix.is_equals this.opencv_mat that.opencv_mat @@ -69,18 +113,38 @@ type Matrix to_json : Json to_json = Json.String this.opencv_mat.to_text +## Create the matrix with all elements - zeros. + + > Example + Create a matrix. + Matrix.zeros 2 2 . to_vector == [0, 0, 0, 0] zeros : Integer -> Integer -> Integer -> Matrix zeros rows columns channels=1 = Matrix (Java_Matrix.zeros rows columns channels) +## Create the matrix with all elements - ones. + + > Example + Create a matrix. + Matrix.ones 2 2 channels=2 . to_vector == [1, 1, 1, 1, 1, 1, 1, 1] ones : Integer -> Integer -> Integer -> Matrix ones rows columns channels=1 = Matrix (Java_Matrix.ones rows columns channels) +## Create an identity matrix containing ones on a main diagonal. + + > Example + Create a matrix. + Matrix.eye 2 2 channels=1 . to_vector == [1, 0, 0, 1] eye : Integer -> Integer -> Integer -> Matrix eye rows columns channels=1 = Matrix (Java_Matrix.eye rows columns channels) +## Create a matrix from the vector. + + > Example + Create a matrix. + Matrix.from_vecor [1, 1, 0, 0] . to_vector == [1, 1, 0, 0] from_vector : Vector -> Integer -> Integer -> Matrix from_vector values rows=1 channels=1 = Matrix (Java_Matrix.from_vector values.to_array channels rows) diff --git a/distribution/std-lib/Standard/src/Image/Data/Matrix/Internal.enso b/distribution/std-lib/Standard/src/Image/Data/Matrix/Internal.enso index 3cfa0803ba3d2..595fab3e8a047 100644 --- a/distribution/std-lib/Standard/src/Image/Data/Matrix/Internal.enso +++ b/distribution/std-lib/Standard/src/Image/Data/Matrix/Internal.enso @@ -5,12 +5,6 @@ polyglot java import org.enso.image.data.Matrix as Java_Matrix polyglot java import org.opencv.core.Mat polyglot java import org.opencv.core.Scalar -## PRIVATE -create rows cols mat_type values = - opencv_scalar = Scalar.new values.to_array - opencv_mat = Mat.new rows cols mat_type opencv_scalar - Matrix.Matrix opencv_mat - ## PRIVATE core_op mat value function = result = Mat.new