diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp index 0077ae4853..779318c33f 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -1219,16 +1219,16 @@ CV__DNN_INLINE_NS_BEGIN { CV_WRAP Image2BlobParams(); CV_WRAP Image2BlobParams(const Scalar& scalefactor, const Size& size = Size(), const Scalar& mean = Scalar(), - bool swapRB = false, int ddepth = CV_32F, DataLayout datalayout = DNN_LAYOUT_NCHW, - ImagePaddingMode mode = DNN_PMODE_NULL, Scalar borderValue = 0.0); + bool swapRB = false, int ddepth = CV_32F, dnn::DataLayout datalayout = DNN_LAYOUT_NCHW, + ImagePaddingMode mode = dnn::DNN_PMODE_NULL, Scalar borderValue = 0.0); CV_PROP_RW Scalar scalefactor; //!< scalefactor multiplier for input image values. CV_PROP_RW Size size; //!< Spatial size for output image. CV_PROP_RW Scalar mean; //!< Scalar with mean values which are subtracted from channels. CV_PROP_RW bool swapRB; //!< Flag which indicates that swap first and last channels CV_PROP_RW int ddepth; //!< Depth of output blob. Choose CV_32F or CV_8U. - CV_PROP_RW DataLayout datalayout; //!< Order of output dimensions. Choose DNN_LAYOUT_NCHW or DNN_LAYOUT_NHWC. - CV_PROP_RW ImagePaddingMode paddingmode; //!< Image padding mode. @see ImagePaddingMode. + CV_PROP_RW dnn::DataLayout datalayout; //!< Order of output dimensions. Choose DNN_LAYOUT_NCHW or DNN_LAYOUT_NHWC. + CV_PROP_RW dnn::ImagePaddingMode paddingmode; //!< Image padding mode. @see ImagePaddingMode. CV_PROP_RW Scalar borderValue; //!< Value used in padding mode for padding. /** @brief Get rectangle coordinates in original image system from rectangle in blob coordinates. diff --git a/modules/dnn/misc/java/test/DnnBlobFromImageWithParamsTest.java b/modules/dnn/misc/java/test/DnnBlobFromImageWithParamsTest.java new file mode 100644 index 0000000000..f55576eb61 --- /dev/null +++ b/modules/dnn/misc/java/test/DnnBlobFromImageWithParamsTest.java @@ -0,0 +1,134 @@ +package org.opencv.test.dnn; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.opencv.core.Core; +import org.opencv.core.CvType; +import org.opencv.core.Mat; +import org.opencv.core.Scalar; +import org.opencv.core.Size; +import org.opencv.core.Range; +import org.opencv.dnn.Dnn; +import org.opencv.dnn.Image2BlobParams; +import org.opencv.test.OpenCVTestCase; + +public class DnnBlobFromImageWithParamsTest extends OpenCVTestCase { + + public void testBlobFromImageWithParamsNHWCScalarScale() + { + Mat img = new Mat(10, 10, CvType.CV_8UC4, new Scalar(0, 1, 2, 3)); + Scalar scalefactor = new Scalar(0.1, 0.2, 0.3, 0.4); + + Image2BlobParams params = new Image2BlobParams(); + params.set_scalefactor(scalefactor); + params.set_datalayout(Dnn.DNN_LAYOUT_NHWC); + + Mat blob = Dnn.blobFromImageWithParams(img, params); // [1, 10, 10, 4] + + float[] expectedValues = { (float)scalefactor.val[0] * 0, (float)scalefactor.val[1] * 1, (float)scalefactor.val[2] * 2, (float)scalefactor.val[3] * 3 }; // Target Value. + for (int h = 0; h < 10; h++) + { + for (int w = 0; w < 10; w++) + { + float[] actualValues = new float[4]; + blob.get(new int[]{0, h, w, 0}, actualValues); + for (int c = 0; c < 4; c++) + { + // Check equal + assertEquals(expectedValues[c], actualValues[c]); + } + } + } + } + + public void testBlobFromImageWithParamsCustomPaddingLetterBox() + { + Mat img = new Mat(40, 20, CvType.CV_8UC4, new Scalar(0, 1, 2, 3)); + + // Custom padding value that you have added + Scalar customPaddingValue = new Scalar(5, 6, 7, 8); // Example padding value + Size targetSize = new Size(20, 20); + + Mat targetImg = img.clone(); + Core.copyMakeBorder(targetImg, targetImg, 0, 0, (int)targetSize.width / 2, (int)targetSize.width / 2, Core.BORDER_CONSTANT, customPaddingValue); + + // Set up Image2BlobParams with your new functionality + Image2BlobParams params = new Image2BlobParams(); + params.set_size(targetSize); + params.set_paddingmode(Dnn.DNN_PMODE_LETTERBOX); + params.set_borderValue(customPaddingValue); // Use your new feature here + + // Create blob with custom padding + Mat blob = Dnn.blobFromImageWithParams(img, params); + + // Create target blob for comparison + Mat targetBlob = Dnn.blobFromImage(targetImg, 1.0, targetSize); + + assertEquals(0, Core.norm(targetBlob, blob, Core.NORM_INF), EPS); + } + + public void testBlobFromImageWithParams4chLetterBox() + { + Mat img = new Mat(40, 20, CvType.CV_8UC4, new Scalar(0, 1, 2, 3)); + + // Construct target mat. + Mat[] targetChannels = new Mat[4]; + + // The letterbox will add zero at the left and right of output blob. + // After the letterbox, every row data would have same value showing as valVec. + byte[] valVec = { 0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0}; + + Mat rowM = new Mat(1, 20, CvType.CV_8UC1); + rowM.put(0, 0, valVec); + for (int i = 0; i < 4; i++) { + Core.multiply(rowM, new Scalar(i), targetChannels[i] = new Mat()); + } + + Mat targetImg = new Mat(); + Core.merge(Arrays.asList(targetChannels), targetImg); + Size targetSize = new Size(20, 20); + + Image2BlobParams params = new Image2BlobParams(); + params.set_size(targetSize); + params.set_paddingmode(Dnn.DNN_PMODE_LETTERBOX); + Mat blob = Dnn.blobFromImageWithParams(img, params); + Mat targetBlob = Dnn.blobFromImage(targetImg, 1.0, targetSize); // only convert data from uint8 to float32. + + assertEquals(0, Core.norm(targetBlob, blob, Core.NORM_INF), EPS); + } + + public void testBlobFromImageWithParams4chMultiImage() + { + Mat img = new Mat(10, 10, CvType.CV_8UC4, new Scalar(0, 1, 2, 3)); + + Scalar scalefactor = new Scalar(0.1, 0.2, 0.3, 0.4); + + Image2BlobParams param = new Image2BlobParams(); + param.set_scalefactor(scalefactor); + param.set_datalayout(Dnn.DNN_LAYOUT_NHWC); + + List images = new ArrayList<>(); + images.add(img); + Mat img2 = new Mat(); + Core.multiply(img, Scalar.all(2), img2); + images.add(img2); + + Mat blobs = Dnn.blobFromImagesWithParams(images, param); + + Range[] ranges = new Range[4]; + ranges[0] = new Range(0, 1); + ranges[1] = new Range(0, blobs.size(1)); + ranges[2] = new Range(0, blobs.size(2)); + ranges[3] = new Range(0, blobs.size(3)); + + Mat blob0 = blobs.submat(ranges).clone(); + + ranges[0] = new Range(1, 2); + Mat blob1 = blobs.submat(ranges).clone(); + + Core.multiply(blob0, Scalar.all(2), blob0); + + assertEquals(0, Core.norm(blob0, blob1, Core.NORM_INF), EPS); + } +} diff --git a/modules/objdetect/include/opencv2/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect.hpp index 7f11890608..ed0d6f76ac 100644 --- a/modules/objdetect/include/opencv2/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect.hpp @@ -741,10 +741,10 @@ public: CV_PROP_RW int version; //! The optional level of error correction (by default - the lowest). - CV_PROP_RW CorrectionLevel correction_level; + CV_PROP_RW QRCodeEncoder::CorrectionLevel correction_level; //! The optional encoding mode - Numeric, Alphanumeric, Byte, Kanji, ECI or Structured Append. - CV_PROP_RW EncodeMode mode; + CV_PROP_RW QRCodeEncoder::EncodeMode mode; //! The optional number of QR codes to generate in Structured Append mode. CV_PROP_RW int structure_number;