From f0d2230dd33616f42fa82b440573591cddcf9db3 Mon Sep 17 00:00:00 2001 From: Qing Date: Thu, 25 Oct 2018 13:59:46 -0700 Subject: [PATCH 1/6] add image and image suite --- .../main/scala/org/apache/mxnet/Image.scala | 138 ++++++++++++++++++ .../scala/org/apache/mxnet/ImageSuite.scala | 76 ++++++++++ 2 files changed, 214 insertions(+) create mode 100644 scala-package/core/src/main/scala/org/apache/mxnet/Image.scala create mode 100644 scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala diff --git a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala new file mode 100644 index 000000000000..34323cebdd75 --- /dev/null +++ b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.mxnet + +import java.net.URL + +import scala.collection.mutable +import scala.collection.mutable.{ArrayBuffer, ListBuffer} + +/** + * Image API of Scala package + * enable OpenCV feature + */ +object Image { + + def imDecode (urlStr : String) : NDArrayFuncReturn = { + val url = new URL(urlStr) + val inputStream = url.openStream + val buffer = new Array[Byte](2048) + val arrBuffer = ArrayBuffer[Byte]() + var length = 0 + while (length != -1) { + length = inputStream.read(buffer) + if (length != -1) arrBuffer ++= buffer.slice(0, length) + } + imDecode(arrBuffer.toArray) + } + /** + * Decode image with OpenCV. + * Note: return image in RGB by default, instead of OpenCV's default BGR. + * @param buf Buffer containing binary encoded image + * @param flag Convert decoded image to grayscale (0) or color (1). + * @param to_rgb Whether to convert decoded image + * to mxnet's default RGB format (instead of opencv's default BGR). + * @return org.apache.mxnet.NDArray + */ + def imDecode (buf : Array[Byte], flag : Option[Int] = None, + to_rgb : Option[Boolean] = None, + out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + val nd = NDArray.array(buf.map(_.toFloat), Shape(buf.length)) + val byteND = NDArray.api.cast(nd, "uint8") + val args : ListBuffer[Any] = ListBuffer() + val map : mutable.Map[String, Any] = mutable.Map() + args += byteND + if (flag.isDefined) map("flag") = flag.get + if (to_rgb.isDefined) map("to_rgb") = to_rgb.get + if (out.isDefined) map("out") = out.get + NDArray.genericNDArrayFunctionInvoke("_cvimdecode", args, map.toMap) + } + + /** + * Read and decode image with OpenCV. + * Note: return image in RGB by default, instead of OpenCV's default BGR. + * @param filename Name of the image file to be loaded. + * @param flag Convert decoded image to grayscale (0) or color (1). + * @param to_rgb Whether to convert decoded image to mxnet's default RGB format + * (instead of opencv's default BGR). + * @return org.apache.mxnet.NDArray in HWC format + */ + def imRead (filename : String, flag : Option[Int] = None, + to_rgb : Option[Boolean] = None, + out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + val args : ListBuffer[Any] = ListBuffer() + val map : mutable.Map[String, Any] = mutable.Map() + map("filename") = filename + if (flag.isDefined) map("flag") = flag.get + if (to_rgb.isDefined) map("to_rgb") = to_rgb.get + if (out.isDefined) map("out") = out.get + NDArray.genericNDArrayFunctionInvoke("_cvimread", args, map.toMap) + } + + /** + * Resize image with OpenCV. + * @param src source image in NDArray + * @param w Width of resized image. + * @param h Height of resized image. + * @param interp Interpolation method (default=cv2.INTER_LINEAR). + * @return org.apache.mxnet.NDArray + */ + def imResize (src : org.apache.mxnet.NDArray, w : Int, h : Int, + interp : Option[Int] = None, + out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + val args : ListBuffer[Any] = ListBuffer() + val map : mutable.Map[String, Any] = mutable.Map() + args += src + map("w") = w + map("h") = h + if (interp.isDefined) map("interp") = interp.get + if (out.isDefined) map("out") = out.get + NDArray.genericNDArrayFunctionInvoke("_cvimresize", args, map.toMap) + } + + /** + * Pad image border with OpenCV. + * @param src source image + * @param top Top margin. + * @param bot Bottom margin. + * @param left Left margin. + * @param right Right margin. + * @param typeOf Filling type (default=cv2.BORDER_CONSTANT). + * @param value (Deprecated! Use ``values`` instead.) Fill with single value. + * @param values Fill with value(RGB[A] or gray), up to 4 channels. + * @return org.apache.mxnet.NDArray + */ + def copyMakeBorder (src : org.apache.mxnet.NDArray, top : Int, bot : Int, + left : Int, right : Int, typeOf : Option[Int] = None, + value : Option[Double] = None, values : Option[Any] = None, + out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + val args : ListBuffer[Any] = ListBuffer() + val map : mutable.Map[String, Any] = mutable.Map() + args += src + map("top") = top + map("bot") = bot + map("left") = left + map("right") = right + if (typeOf.isDefined) map("type") = typeOf.get + if (value.isDefined) map("value") = value.get + if (values.isDefined) map("values") = values.get + if (out.isDefined) map("out") = out.get + NDArray.genericNDArrayFunctionInvoke("_cvcopyMakeBorder", args, map.toMap) + } + +} diff --git a/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala new file mode 100644 index 000000000000..5b47039a8f9c --- /dev/null +++ b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.mxnet + +import java.io.File +import java.net.URL + +import org.apache.commons.io.FileUtils +import org.scalatest.{BeforeAndAfterAll, FunSuite} +import org.slf4j.LoggerFactory + +class ImageSuite extends FunSuite with BeforeAndAfterAll { + private var imLocation = "" + private val logger = LoggerFactory.getLogger(classOf[ImageSuite]) + + private def downloadUrl(url: String, filePath: String, maxRetry: Option[Int] = None) : Unit = { + val tmpFile = new File(filePath) + var retry = maxRetry.getOrElse(3) + var success = false + if (!tmpFile.exists()) { + while (retry > 0 && !success) { + try { + FileUtils.copyURLToFile(new URL(url), tmpFile) + success = true + } catch { + case e: Exception => retry -= 1 + } + } + } else { + success = true + } + if (!success) throw new Exception(s"$url Download failed!") + } + + override def beforeAll(): Unit = { + val tempDirPath = System.getProperty("java.io.tmpdir") + imLocation = tempDirPath + "/inputImages/Pug-Cookie.jpg" + downloadUrl("https://s3.amazonaws.com/model-server/inputs/Pug-Cookie.jpg", + imLocation) + } + + test("Test load image") { + val nd = Image.imRead(imLocation) + logger.info(s"OpenCV load image with shape: ${nd.shape}") + require(nd.shape == Shape(576, 1024, 3), "image shape not Match!") + } + + test("Test load image from Socket") { + val nd = Image.imDecode("https://s3.amazonaws.com/model-server/inputs/Pug-Cookie.jpg") + logger.info(s"OpenCV load image with shape: ${nd.shape}") + require(nd.shape == Shape(576, 1024, 3), "image shape not Match!") + } + + test("Test resize image") { + val nd = Image.imRead(imLocation) + val resizeIm = Image.imResize(nd, 224, 224) + logger.info(s"OpenCV resize image with shape: ${resizeIm.shape}") + require(resizeIm.shape == Shape(224, 224, 3), "image shape not Match!") + } + +} From e278015288da1a2e91407710a53113581b3f31f9 Mon Sep 17 00:00:00 2001 From: Qing Date: Thu, 25 Oct 2018 18:56:09 -0700 Subject: [PATCH 2/6] apply toImage function and tests --- .../main/scala/org/apache/mxnet/Image.scala | 80 ++++++++++++++++--- .../scala/org/apache/mxnet/ImageSuite.scala | 16 +++- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala index 34323cebdd75..80704076d257 100644 --- a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala +++ b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala @@ -16,7 +16,12 @@ */ package org.apache.mxnet +// scalastyle:off +import java.awt.image.BufferedImage +import java.io.File +import javax.imageio.ImageIO +// scalastyle:on import java.net.URL import scala.collection.mutable @@ -28,18 +33,6 @@ import scala.collection.mutable.{ArrayBuffer, ListBuffer} */ object Image { - def imDecode (urlStr : String) : NDArrayFuncReturn = { - val url = new URL(urlStr) - val inputStream = url.openStream - val buffer = new Array[Byte](2048) - val arrBuffer = ArrayBuffer[Byte]() - var length = 0 - while (length != -1) { - length = inputStream.read(buffer) - if (length != -1) arrBuffer ++= buffer.slice(0, length) - } - imDecode(arrBuffer.toArray) - } /** * Decode image with OpenCV. * Note: return image in RGB by default, instead of OpenCV's default BGR. @@ -47,7 +40,7 @@ object Image { * @param flag Convert decoded image to grayscale (0) or color (1). * @param to_rgb Whether to convert decoded image * to mxnet's default RGB format (instead of opencv's default BGR). - * @return org.apache.mxnet.NDArray + * @return NDArray in HWC format */ def imDecode (buf : Array[Byte], flag : Option[Int] = None, to_rgb : Option[Boolean] = None, @@ -63,6 +56,26 @@ object Image { NDArray.genericNDArrayFunctionInvoke("_cvimdecode", args, map.toMap) } + /** + * Same imageDecode with URL Enabled + * @param urlStr URL link to the image + * @return NDArray in HWC format + */ + def imDecodeURL (urlStr : String, flag : Option[Int] = None, + to_rgb : Option[Boolean] = None, + out : Option[NDArray] = None) : NDArrayFuncReturn = { + val url = new URL(urlStr) + val inputStream = url.openStream + val buffer = new Array[Byte](2048) + val arrBuffer = ArrayBuffer[Byte]() + var length = 0 + while (length != -1) { + length = inputStream.read(buffer) + if (length != -1) arrBuffer ++= buffer.slice(0, length) + } + imDecode(arrBuffer.toArray) + } + /** * Read and decode image with OpenCV. * Note: return image in RGB by default, instead of OpenCV's default BGR. @@ -135,4 +148,45 @@ object Image { NDArray.genericNDArrayFunctionInvoke("_cvcopyMakeBorder", args, map.toMap) } + /** + * Do a fixed crop on the image + * @param src Src image in NDArray + * @param x0 starting x point + * @param y0 starting y point + * @param w width of the image + * @param h height of the image + * @return cropped NDArray + */ + def fixedCrop(src : NDArray, x0 : Int, y0 : Int, w : Int, h : Int) : NDArray = { + NDArray.api.crop(src, Shape(y0, x0, 0), Shape(y0 + h, x0 + w, src.shape.get(2))) + } + + /** + * Convert a NDArray image to a real image + * The time cost will increase if the image resolution is big + * @param src Source image file in RGB + * @param filePath output file path + * @param fileType decoding type, such as png, jpg + */ + def toImage(src : NDArray, filePath : String, fileType : Option[String] = None) : Unit = { + require(src.dtype == DType.UInt8, "The input NDArray must be bytes") + require(src.shape.length == 3, "The input should contains height, width and channel") + val height = src.shape.get(0) + val width = src.shape.get(1) + val img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) + (0 until height).par.foreach(r => { + (0 until width).par.foreach(c => { + val arr = src.at(r).at(c).toArray + // NDArray in RGB + val red = arr(0).toByte & 0xFF + val green = arr(1).toByte & 0xFF + val blue = arr(2).toByte & 0xFF + val rgb = (red << 16) | (green << 8) | blue + img.setRGB(c, r, rgb) + }) + }) + val temp = if (fileType.isDefined) fileType.get else "png" + ImageIO.write(img, temp, new File(filePath)) + } + } diff --git a/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala index 5b47039a8f9c..74d0b75cb8ba 100644 --- a/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala +++ b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala @@ -61,7 +61,7 @@ class ImageSuite extends FunSuite with BeforeAndAfterAll { } test("Test load image from Socket") { - val nd = Image.imDecode("https://s3.amazonaws.com/model-server/inputs/Pug-Cookie.jpg") + val nd = Image.imDecodeURL("https://s3.amazonaws.com/model-server/inputs/Pug-Cookie.jpg") logger.info(s"OpenCV load image with shape: ${nd.shape}") require(nd.shape == Shape(576, 1024, 3), "image shape not Match!") } @@ -73,4 +73,18 @@ class ImageSuite extends FunSuite with BeforeAndAfterAll { require(resizeIm.shape == Shape(224, 224, 3), "image shape not Match!") } + test("Test crop image") { + val nd = Image.imRead(imLocation) + val nd2 = Image.fixedCrop(nd, 0, 0, 224, 224) + require(nd2.shape == Shape(224, 224, 3), "image shape not Match!") + } + + test("Test convert to Image") { + val nd = Image.imRead(imLocation) + val resizeIm = Image.imResize(nd, 224, 224) + val tempDirPath = System.getProperty("java.io.tmpdir") + Image.toImage(resizeIm, tempDirPath + "/inputImages/out.png") + logger.info(s"converted image stored in ${tempDirPath + "/inputImages/out.png"}") + } + } From ec696207bed2d53dcacd67892253057f5bcf6902 Mon Sep 17 00:00:00 2001 From: Qing Date: Sat, 27 Oct 2018 16:19:51 -0700 Subject: [PATCH 3/6] bug fix --- scala-package/core/src/main/scala/org/apache/mxnet/Image.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala index 80704076d257..01dabf79e820 100644 --- a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala +++ b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala @@ -73,7 +73,7 @@ object Image { length = inputStream.read(buffer) if (length != -1) arrBuffer ++= buffer.slice(0, length) } - imDecode(arrBuffer.toArray) + imDecode(arrBuffer.toArray, flag, to_rgb, out) } /** From 57a7cc38501af1db044e163805ddc7ca78743c9c Mon Sep 17 00:00:00 2001 From: Qing Date: Tue, 30 Oct 2018 15:15:04 -0700 Subject: [PATCH 4/6] apply the commented change --- .../main/scala/org/apache/mxnet/Image.scala | 41 ++++++++----------- .../scala/org/apache/mxnet/ImageSuite.scala | 8 +++- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala index 01dabf79e820..caa4b1d8fd49 100644 --- a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala +++ b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala @@ -18,11 +18,8 @@ package org.apache.mxnet // scalastyle:off import java.awt.image.BufferedImage -import java.io.File - -import javax.imageio.ImageIO // scalastyle:on -import java.net.URL +import java.io.InputStream import scala.collection.mutable import scala.collection.mutable.{ArrayBuffer, ListBuffer} @@ -42,30 +39,28 @@ object Image { * to mxnet's default RGB format (instead of opencv's default BGR). * @return NDArray in HWC format */ - def imDecode (buf : Array[Byte], flag : Option[Int] = None, - to_rgb : Option[Boolean] = None, - out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + def imDecode (buf : Array[Byte], flag : Int, + to_rgb : Boolean, + out : Option[NDArray]) : NDArray = { val nd = NDArray.array(buf.map(_.toFloat), Shape(buf.length)) val byteND = NDArray.api.cast(nd, "uint8") val args : ListBuffer[Any] = ListBuffer() val map : mutable.Map[String, Any] = mutable.Map() args += byteND - if (flag.isDefined) map("flag") = flag.get - if (to_rgb.isDefined) map("to_rgb") = to_rgb.get + map("flag") = flag + map("to_rgb") = to_rgb if (out.isDefined) map("out") = out.get NDArray.genericNDArrayFunctionInvoke("_cvimdecode", args, map.toMap) } /** - * Same imageDecode with URL Enabled - * @param urlStr URL link to the image + * Same imageDecode with InputStream + * @param inputStream the inputStream of the image * @return NDArray in HWC format */ - def imDecodeURL (urlStr : String, flag : Option[Int] = None, - to_rgb : Option[Boolean] = None, - out : Option[NDArray] = None) : NDArrayFuncReturn = { - val url = new URL(urlStr) - val inputStream = url.openStream + def imDecode (inputStream : InputStream, flag : Int = 1, + to_rgb : Boolean = true, + out : Option[NDArray] = None) : NDArray = { val buffer = new Array[Byte](2048) val arrBuffer = ArrayBuffer[Byte]() var length = 0 @@ -87,7 +82,7 @@ object Image { */ def imRead (filename : String, flag : Option[Int] = None, to_rgb : Option[Boolean] = None, - out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + out : Option[NDArray] = None) : NDArray = { val args : ListBuffer[Any] = ListBuffer() val map : mutable.Map[String, Any] = mutable.Map() map("filename") = filename @@ -107,7 +102,7 @@ object Image { */ def imResize (src : org.apache.mxnet.NDArray, w : Int, h : Int, interp : Option[Int] = None, - out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + out : Option[NDArray] = None) : NDArray = { val args : ListBuffer[Any] = ListBuffer() val map : mutable.Map[String, Any] = mutable.Map() args += src @@ -133,7 +128,7 @@ object Image { def copyMakeBorder (src : org.apache.mxnet.NDArray, top : Int, bot : Int, left : Int, right : Int, typeOf : Option[Int] = None, value : Option[Double] = None, values : Option[Any] = None, - out : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn = { + out : Option[NDArray] = None) : NDArray = { val args : ListBuffer[Any] = ListBuffer() val map : mutable.Map[String, Any] = mutable.Map() args += src @@ -165,10 +160,9 @@ object Image { * Convert a NDArray image to a real image * The time cost will increase if the image resolution is big * @param src Source image file in RGB - * @param filePath output file path - * @param fileType decoding type, such as png, jpg + * @return Buffered Image */ - def toImage(src : NDArray, filePath : String, fileType : Option[String] = None) : Unit = { + def toImage(src : NDArray) : BufferedImage = { require(src.dtype == DType.UInt8, "The input NDArray must be bytes") require(src.shape.length == 3, "The input should contains height, width and channel") val height = src.shape.get(0) @@ -185,8 +179,7 @@ object Image { img.setRGB(c, r, rgb) }) }) - val temp = if (fileType.isDefined) fileType.get else "png" - ImageIO.write(img, temp, new File(filePath)) + img } } diff --git a/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala index 74d0b75cb8ba..936ae7c81eae 100644 --- a/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala +++ b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala @@ -20,6 +20,7 @@ package org.apache.mxnet import java.io.File import java.net.URL +import javax.imageio.ImageIO import org.apache.commons.io.FileUtils import org.scalatest.{BeforeAndAfterAll, FunSuite} import org.slf4j.LoggerFactory @@ -61,7 +62,9 @@ class ImageSuite extends FunSuite with BeforeAndAfterAll { } test("Test load image from Socket") { - val nd = Image.imDecodeURL("https://s3.amazonaws.com/model-server/inputs/Pug-Cookie.jpg") + val url = new URL("https://s3.amazonaws.com/model-server/inputs/Pug-Cookie.jpg") + val inputStream = url.openStream + val nd = Image.imDecode(inputStream) logger.info(s"OpenCV load image with shape: ${nd.shape}") require(nd.shape == Shape(576, 1024, 3), "image shape not Match!") } @@ -83,7 +86,8 @@ class ImageSuite extends FunSuite with BeforeAndAfterAll { val nd = Image.imRead(imLocation) val resizeIm = Image.imResize(nd, 224, 224) val tempDirPath = System.getProperty("java.io.tmpdir") - Image.toImage(resizeIm, tempDirPath + "/inputImages/out.png") + val img = Image.toImage(resizeIm) + ImageIO.write(img, "png", new File(tempDirPath + "/inputImages/out.png")) logger.info(s"converted image stored in ${tempDirPath + "/inputImages/out.png"}") } From 67110ff72a528c2057c8cf59bd3283017f3ddbf2 Mon Sep 17 00:00:00 2001 From: Qing Date: Thu, 1 Nov 2018 10:48:09 -0700 Subject: [PATCH 5/6] add test to apply border --- .../core/src/test/scala/org/apache/mxnet/ImageSuite.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala index 936ae7c81eae..67815ad6c108 100644 --- a/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala +++ b/scala-package/core/src/test/scala/org/apache/mxnet/ImageSuite.scala @@ -82,6 +82,12 @@ class ImageSuite extends FunSuite with BeforeAndAfterAll { require(nd2.shape == Shape(224, 224, 3), "image shape not Match!") } + test("Test apply border") { + val nd = Image.imRead(imLocation) + val nd2 = Image.copyMakeBorder(nd, 1, 1, 1, 1) + require(nd2.shape == Shape(578, 1026, 3), s"image shape not Match!") + } + test("Test convert to Image") { val nd = Image.imRead(imLocation) val resizeIm = Image.imResize(nd, 224, 224) From eea7b7e1296d46c123a549fdb2b51786fe649fe6 Mon Sep 17 00:00:00 2001 From: Qing Date: Thu, 1 Nov 2018 14:56:37 -0700 Subject: [PATCH 6/6] fix scalastyle --- .../main/scala/org/apache/mxnet/Image.scala | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala index caa4b1d8fd49..43f81a22a409 100644 --- a/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala +++ b/scala-package/core/src/main/scala/org/apache/mxnet/Image.scala @@ -39,9 +39,9 @@ object Image { * to mxnet's default RGB format (instead of opencv's default BGR). * @return NDArray in HWC format */ - def imDecode (buf : Array[Byte], flag : Int, - to_rgb : Boolean, - out : Option[NDArray]) : NDArray = { + def imDecode(buf: Array[Byte], flag: Int, + to_rgb: Boolean, + out: Option[NDArray]): NDArray = { val nd = NDArray.array(buf.map(_.toFloat), Shape(buf.length)) val byteND = NDArray.api.cast(nd, "uint8") val args : ListBuffer[Any] = ListBuffer() @@ -58,9 +58,9 @@ object Image { * @param inputStream the inputStream of the image * @return NDArray in HWC format */ - def imDecode (inputStream : InputStream, flag : Int = 1, - to_rgb : Boolean = true, - out : Option[NDArray] = None) : NDArray = { + def imDecode(inputStream: InputStream, flag: Int = 1, + to_rgb: Boolean = true, + out: Option[NDArray] = None): NDArray = { val buffer = new Array[Byte](2048) val arrBuffer = ArrayBuffer[Byte]() var length = 0 @@ -80,9 +80,9 @@ object Image { * (instead of opencv's default BGR). * @return org.apache.mxnet.NDArray in HWC format */ - def imRead (filename : String, flag : Option[Int] = None, - to_rgb : Option[Boolean] = None, - out : Option[NDArray] = None) : NDArray = { + def imRead(filename: String, flag: Option[Int] = None, + to_rgb: Option[Boolean] = None, + out: Option[NDArray] = None): NDArray = { val args : ListBuffer[Any] = ListBuffer() val map : mutable.Map[String, Any] = mutable.Map() map("filename") = filename @@ -100,9 +100,9 @@ object Image { * @param interp Interpolation method (default=cv2.INTER_LINEAR). * @return org.apache.mxnet.NDArray */ - def imResize (src : org.apache.mxnet.NDArray, w : Int, h : Int, - interp : Option[Int] = None, - out : Option[NDArray] = None) : NDArray = { + def imResize(src: org.apache.mxnet.NDArray, w: Int, h: Int, + interp: Option[Int] = None, + out: Option[NDArray] = None): NDArray = { val args : ListBuffer[Any] = ListBuffer() val map : mutable.Map[String, Any] = mutable.Map() args += src @@ -125,10 +125,10 @@ object Image { * @param values Fill with value(RGB[A] or gray), up to 4 channels. * @return org.apache.mxnet.NDArray */ - def copyMakeBorder (src : org.apache.mxnet.NDArray, top : Int, bot : Int, - left : Int, right : Int, typeOf : Option[Int] = None, - value : Option[Double] = None, values : Option[Any] = None, - out : Option[NDArray] = None) : NDArray = { + def copyMakeBorder(src: org.apache.mxnet.NDArray, top: Int, bot: Int, + left: Int, right: Int, typeOf: Option[Int] = None, + value: Option[Double] = None, values: Option[Any] = None, + out: Option[NDArray] = None): NDArray = { val args : ListBuffer[Any] = ListBuffer() val map : mutable.Map[String, Any] = mutable.Map() args += src @@ -152,7 +152,7 @@ object Image { * @param h height of the image * @return cropped NDArray */ - def fixedCrop(src : NDArray, x0 : Int, y0 : Int, w : Int, h : Int) : NDArray = { + def fixedCrop(src: NDArray, x0: Int, y0: Int, w: Int, h: Int): NDArray = { NDArray.api.crop(src, Shape(y0, x0, 0), Shape(y0 + h, x0 + w, src.shape.get(2))) } @@ -162,7 +162,7 @@ object Image { * @param src Source image file in RGB * @return Buffered Image */ - def toImage(src : NDArray) : BufferedImage = { + def toImage(src: NDArray): BufferedImage = { require(src.dtype == DType.UInt8, "The input NDArray must be bytes") require(src.shape.length == 3, "The input should contains height, width and channel") val height = src.shape.get(0)