From b05c42471ef3149f9deb79d4d36d09e2a21e14f7 Mon Sep 17 00:00:00 2001 From: Jarek Sacha Date: Fri, 22 Jul 2022 21:20:00 -0400 Subject: [PATCH] API: prefer use of immutable IndexedSeq instead of Array #72 --- .../color/calibration/chart/ChartFrame.scala | 6 ++-- .../color/calibration/chart/ColorChip.scala | 6 ++-- .../calibration/chart/GridChartFrame.scala | 6 ++-- .../calibration/regression/Regression.scala | 35 +++++++++++++------ .../color/util/PerspectiveTransform.scala | 26 ++++++++++++-- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ChartFrame.scala b/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ChartFrame.scala index 79f9445..cc4398a 100644 --- a/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ChartFrame.scala +++ b/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ChartFrame.scala @@ -44,14 +44,14 @@ object ChartFrame { */ class ChartFrame( refOutline: IndexedSeq[Point2D], - refChipOutlines: IndexedSeq[Seq[Point2D]], + refChipOutlines: IndexedSeq[IndexedSeq[Point2D]], final val alignmentTransform: PerspectiveTransform /*= new PerspectiveTransform()*/ ) { require(refOutline.length == 4, s"The reference outline must have 4 points, got ${refOutline.length}.") private val _referenceOutline: IndexedSeq[Point2D] = deepCopy(refOutline) - private val _chipOutlines: IndexedSeq[Seq[Point2D]] = refChipOutlines.map(deepCopy) + private val _chipOutlines: IndexedSeq[IndexedSeq[Point2D]] = refChipOutlines.map(deepCopy) /** * Outline of the reference chart as a sequence of 4 corner points: top-left, top-right, bottom-right, bottom-left. @@ -61,7 +61,7 @@ class ChartFrame( /** * Outlines of the reference chips. OOutlines are polygons, may have 3 or more vertices. */ - final def referenceChipOutlines: IndexedSeq[Seq[Point2D]] = _chipOutlines.map(deepCopy) + final def referenceChipOutlines: IndexedSeq[IndexedSeq[Point2D]] = _chipOutlines.map(deepCopy) /** * Creates a copy of this chart that has its chip outline aligned to given ROI. diff --git a/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ColorChip.scala b/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ColorChip.scala index 4c41ddc..a0a39d0 100644 --- a/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ColorChip.scala +++ b/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/ColorChip.scala @@ -1,6 +1,6 @@ /* * Image/J Plugins - * Copyright (C) 2002-2021 Jarek Sacha + * Copyright (C) 2002-2022 Jarek Sacha * Author's email: jpsacha at gmail dot com * * This library is free software; you can redistribute it and/or @@ -54,7 +54,7 @@ object ColorChip { new ColorChip( name, color, - List( + IndexedSeq( point2D(column + margin, row + margin), point2D(column + 1 - margin, row + margin), point2D(column + 1 - margin, row + 1 - margin), @@ -74,4 +74,4 @@ object ColorChip { * @param outline * outline describing the chip and its location. */ -class ColorChip(val name: String, val color: Lab, val outline: Seq[Point2D]) +class ColorChip(val name: String, val color: Lab, val outline: IndexedSeq[Point2D]) diff --git a/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/GridChartFrame.scala b/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/GridChartFrame.scala index 2b5bea5..6c64d45 100644 --- a/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/GridChartFrame.scala +++ b/ijp-color/src/main/scala/ij_plugins/color/calibration/chart/GridChartFrame.scala @@ -1,6 +1,6 @@ /* * Image/J Plugins - * Copyright (C) 2002-2021 Jarek Sacha + * Copyright (C) 2002-2022 Jarek Sacha * Author's email: jpsacha at gmail dot com * * This library is free software; you can redistribute it and/or @@ -30,12 +30,12 @@ import java.awt.geom.Point2D import scala.collection.compat.immutable.ArraySeq object GridChartFrame { - private def createChipOutlines(nbColumns: Int, nbRows: Int, chipMargin: Double): IndexedSeq[Seq[Point2D]] = { + private def createChipOutlines(nbColumns: Int, nbRows: Int, chipMargin: Double): IndexedSeq[IndexedSeq[Point2D]] = { require(nbColumns > 0) require(nbRows > 0) for { - row <- 0 until nbRows + row <- 0 until nbRows column <- 0 until nbColumns } yield { Seq( diff --git a/ijp-color/src/main/scala/ij_plugins/color/calibration/regression/Regression.scala b/ijp-color/src/main/scala/ij_plugins/color/calibration/regression/Regression.scala index 4c88c18..24fade8 100644 --- a/ijp-color/src/main/scala/ij_plugins/color/calibration/regression/Regression.scala +++ b/ijp-color/src/main/scala/ij_plugins/color/calibration/regression/Regression.scala @@ -59,17 +59,13 @@ object Regression { /** * Compute linear fit coefficient `s = A*o` if `noIntercept` is true or `s = A*o + b` if `noIntercept` is `false`. * - * @param standard - * array of expected output values. - * @param observation - * array of input values - * @param noIntercept - * true means the model is to be estimated without an intercept term - * @return - * linear fit coefficients + * @param standard array of expected output values. + * @param observation array of input values + * @param noIntercept true means the model is to be estimated without an intercept term + * @return linear fit coefficients */ def regression(standard: Array[Double], - observation: IndexedSeq[IndexedSeq[Double]], + observation: Array[Array[Double]], noIntercept: Boolean ): Regression.Result = { require(standard != null, "Argument `standard` cannot be null.") @@ -86,7 +82,7 @@ object Regression { val regression = new OLSMultipleLinearRegression() regression.setNoIntercept(noIntercept) - regression.newSampleData(standard, toArrayArray(observation)) + regression.newSampleData(standard, observation) Regression.Result( numberOfSamples = standard.length, beta = regression.estimateRegressionParameters, @@ -97,6 +93,21 @@ object Regression { ) } + /** + * Compute linear fit coefficient `s = A*o` if `noIntercept` is true or `s = A*o + b` if `noIntercept` is `false`. + * + * @param standard array of expected output values. + * @param observation array of input values + * @param noIntercept true means the model is to be estimated without an intercept term + * @return linear fit coefficients + */ + def regression(standard: Array[Double], + observation: IndexedSeq[IndexedSeq[Double]], + noIntercept: Boolean + ): Regression.Result = { + regression(standard, toArrayArray(observation), noIntercept) + } + /** * Compute linear fit coefficients that map observations to a reference: `s = A*[o, 1]`. * @@ -110,4 +121,8 @@ object Regression { def createLinear(standard: Array[Double], observation: IndexedSeq[IndexedSeq[Double]]): Regression.Result = { regression(standard, observation, noIntercept = false) } + + def createLinear(standard: Array[Double], observation: Array[Array[Double]]): Regression.Result = { + regression(standard, observation, noIntercept = false) + } } diff --git a/ijp-color/src/main/scala/ij_plugins/color/util/PerspectiveTransform.scala b/ijp-color/src/main/scala/ij_plugins/color/util/PerspectiveTransform.scala index 7dc1cec..6f67088 100644 --- a/ijp-color/src/main/scala/ij_plugins/color/util/PerspectiveTransform.scala +++ b/ijp-color/src/main/scala/ij_plugins/color/util/PerspectiveTransform.scala @@ -1,6 +1,6 @@ /* * Image/J Plugins - * Copyright (C) 2002-2021 Jarek Sacha + * Copyright (C) 2002-2022 Jarek Sacha * Author's email: jpsacha at gmail dot com * * This library is free software; you can redistribute it and/or @@ -317,6 +317,27 @@ object PerspectiveTransform { ) } + def quadToQuad(points1: IndexedSeq[Point2D], points2: IndexedSeq[Point2D]): PerspectiveTransform = { + quadToQuad( + points1(0).getX, + points1(0).getY, + points1(1).getX, + points1(1).getY, + points1(2).getX, + points1(2).getY, + points1(3).getX, + points1(3).getY, + points2(0).getX, + points2(0).getY, + points2(1).getX, + points2(1).getY, + points2(2).getX, + points2(2).getY, + points2(3).getX, + points2(3).getY + ) + } + private final val PERSPECTIVE_DIVIDE_EPSILON: Double = 1.0e-10 } @@ -806,12 +827,11 @@ final class PerspectiveTransform( * @throws java.lang.IllegalArgumentException * if ptSrc is null */ - def transform(points: Seq[Point2D]): immutable.Seq[Point2D] = { + def transform(points: IndexedSeq[Point2D]): immutable.IndexedSeq[Point2D] = { require(points != null, "The input argument 'points' may not be null.") // Conversion `toList` to achieve Scala 2.12 compatibility points .map(p => transform(p)) - .toList } /**