简体   繁体   中英

Merge multiple image into one image with OpenCV

I tried searching for this quite a lot and cant seem to figure it out. All of the threads I read shows that everyone is doing the same thing. But it doesn't seem to work for me.

I want to create a new image and add two images to this created image.

  • For this I'm generating a Mat.zeros onto which I will be adding my two images(lets say A and B. I'll call the zeros Mat G).

  • I scale down the images A and B.

  • I create an ROI on G with the size of A and then copy A to G.submat .

  • I create an ROT on G with size B and then copy B to G.submat .

  • When I finally save G, all I get is a black image( because I generated G as Mat.zeros ) . I'm guessing copyTo is not really copying the content from A to G on the ROI of G.

I'm not sure what I'm doing wrong.

I'm using Kotlin which compiles down to Java.

    @PostConstruct
    fun init() {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }


    @Test
    fun `merge image`() {
        val frameLeft = Imgcodecs.imread("/home/nischit/Downloads/potato1.jpg")
        val frameRight = Imgcodecs.imread("/home/nischit/Downloads/potato2.jpg")
        val frameOutput = Mat.zeros(1920, 1080, frameLeft.depth())

        println(frameLeft.depth())
        println(frameRight.depth())
        println(frameOutput.depth())

        val tempLeft = Mat()
        val tempRight = Mat()

        scaleFrame(frameLeft, tempLeft)
        scaleFrame(frameRight, tempRight)

        println("tempLeft: ${tempLeft.cols()},${tempLeft.rows()}")
        println("tempRight: ${tempRight.cols()},${tempRight.rows()}")

        tempLeft.copyTo(frameOutput.submat(Rect(10, 10, tempLeft.cols(), tempLeft.rows())))
        tempRight.copyTo(frameOutput.submat(Rect(10, 500, tempRight.cols(), tempRight.rows())))
        saveImage(frameOutput, 2)
    }

    fun scaleFrame(frame: Mat, out: Mat, maxWidth: Int = MAX_WIDTH, maxHeight: Int = MAX_HEIGHT) {
        val isFrameInPortraitMode = frame.height() > frame.width()
        val scale = if (isFrameInPortraitMode) {
            (maxHeight * 1.0 / frame.height())
        } else {
            (maxWidth * 1.0 / frame.width())
        }
        Imgproc.resize(frame, out, Size(frame.width() * scale, frame.height() * scale))
    }

    fun saveImage(frame: Mat, i: Int = 0) {
        Imgcodecs.imwrite("/home/nischit/Downloads/potatoGenerated$i.jpg", frame)
    }

Okay, the problem was with channels in the blank image I had created ie frameOutput . All of the inputs have 3 channels while this matrix had 1 channel as I was not initializing it correctly.

Replacing val frameOutput = Mat.zeros(1920, 1080, frameLeft.depth()) with val frameOutput = Mat.zeros(Size(1920.0, 1080.0), CvType.CV_8UC3) worked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM