Ask Your Question

phamtp's profile - activity

2018-11-07 14:56:46 -0600 marked best answer PNG encoding performance difference between 3.1 and 3.2

Encoding a PNG using OpenCV 3.2.0 takes about 2x longer than OpenCV 3.1.0 on an ARM Cortex A9 system, and about 1.4x longer on an x64 system. Does anyone know what causes the difference and whether it can be reduced through build settings? I'll try git bisect between 3.1 and 3.2 to see what caused the difference but wanted to check if anyone already knows. Thanks

Test code (cv.cpp):

#include <iostream>
#include <opencv2/opencv.hpp>

#include <sys/time.h>


int height = 1600;
int width = 1200;

void loadFrame(cv::Mat& frame)
{
    srand (time(NULL));
    printf("generating random image\n");
    int image_format = CV_8U;
    frame.create(height, width, image_format);
    uint8_t* image_ptr = frame.ptr<uint8_t>(0);
    for (int pixel = 0; pixel < int(frame.total()); ++pixel)
    {
        image_ptr[pixel] = rand();
    }
}

bool writeImageToString(const cv::Mat& image, const std::string& extension, std::vector<uint8_t>& buffer)
{
    if (image.empty() || (image.cols == 0 && image.rows == 0))
        return false;

    bool success = true;

    // Set the image compression parameters.
    std::vector<int> params;
    if (extension == ".png")
    {
        params.push_back(cv::IMWRITE_PNG_COMPRESSION);
        params.push_back(6);     // MAX_MEM_LEVEL = 9
        success = cv::imencode(extension, image, buffer, params);
    }
    else if (extension == ".jpg")
    {
        params.push_back(cv::IMWRITE_JPEG_QUALITY);
        params.push_back(90);     // 0...100 (higher is better)
        success = cv::imencode(extension, image, buffer, params);
    }

    return success;
}

void encodeTest(int argc, const char** argv)
{
    int frame_tests = 10;
    int write_tests = 5;
    size_t png_size = 0;
    size_t jpg_size = 0;
    double png_time = 0;
    double jpg_time = 0;
    struct timeval start, end;

    for ( int frame_count = 0; frame_count < frame_tests; frame_count++ )
    {
        cv::Mat frame;
        loadFrame(frame);
        std::vector<uint8_t> buffer;
        gettimeofday(&start, NULL);

        for ( int test_count = 0; test_count < write_tests; test_count++ )
        {
            writeImageToString(frame, ".png", buffer);
        }
        gettimeofday(&end, NULL);
        png_time += ((end.tv_sec - start.tv_sec) * 1000) 
            + (end.tv_usec / 1000 - start.tv_usec / 1000);

        png_size += buffer.size();
        gettimeofday(&start, NULL);

        for ( int test_count = 0; test_count < write_tests; test_count++ )
        {
            writeImageToString(frame, ".jpg", buffer);
        }
        jpg_size += buffer.size();
        gettimeofday(&end, NULL);
        jpg_time += ((end.tv_sec - start.tv_sec) * 1000) 
            + (end.tv_usec / 1000 - start.tv_usec / 1000);

    }
    std::cout << "Avg time PNG: " << png_time / frame_tests / write_tests / 1000 << "sec  JPG: " << jpg_time / frame_tests / write_tests / 1000 << "sec" << std::endl;

    printf("Avg size PNG: %zu     JPG: %zu\n", png_size / 10, jpg_size / 10);
}

int main(int argc, const char** argv)
{
    printf( "OpenCV version : %s\n" , CV_VERSION);

    try
    {
        encodeTest(argc, argv);
    }
    catch (cv::Exception& e)
    {
        printf("OpenCV test error\n");
        throw;
    }
    return 0;
}

This is the CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project( cv )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( cv cv.cpp )
target_link_libraries( cv ${OpenCV_LIBS} )

To generate cross-compile for ARM I used following cmake command:

cmake -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/arm-gnueabi.toolchain.cmake -DGCC_COMPILER_VERSION=5 -DENABLE_NEON=ON -DWITH_OPENMP=1 -DCMAKE_INSTALL_PREFIX=/usr/local ..

For intel x64 system (Ubuntu 14.04) I just used:

cmake .

Sample runs on ARM:

OpenCV version : 3.1.0
Avg time PNG: 0.26792sec  JPG: 0.35374sec
Avg size PNG: 1925061     JPG: 1509208

OpenCV version : 3.1.0
Avg time PNG: 0.26778sec  JPG: 0.35472sec
Avg size PNG: 1925061     JPG: 1509038

OpenCV version : 3.2.0
Avg time PNG: 0 ...
(more)
2018-11-07 14:56:46 -0600 received badge  Scholar (source)
2018-11-07 10:18:12 -0600 received badge  Student (source)
2018-11-07 10:12:05 -0600 received badge  Self-Learner (source)
2018-11-06 19:16:03 -0600 edited answer PNG encoding performance difference between 3.1 and 3.2

I traced down the commit which changed encode timings to https://github.com/opencv/opencv/commit/1b22783d4636a74512171d6

2018-11-06 19:14:00 -0600 commented question PNG encoding performance difference between 3.1 and 3.2

I found the commit which changed the timing for me: https://github.com/opencv/opencv/commit/1b22783d4636a74512171d67b95e

2018-11-06 19:13:52 -0600 commented question PNG encoding performance difference between 3.1 and 3.2

I found the commit which changed the timing for me: https://github.com/opencv/opencv/commit/1b22783d4636a74512171d67b95e

2018-11-06 18:56:42 -0600 edited answer PNG encoding performance difference between 3.1 and 3.2

I traced down the commit which changed encode timings to https://github.com/opencv/opencv/commit/1b22783d4636a74512171d6

2018-11-06 18:55:32 -0600 commented question PNG encoding performance difference between 3.1 and 3.2

I found the commit which changed the timing for me: https://github.com/opencv/opencv/commit/1b22783d4636a74512171d67b95e

2018-11-06 18:36:06 -0600 answered a question PNG encoding performance difference between 3.1 and 3.2

The encode times from the link hash (733fec0) look the same as version 3.2.0 (slower than 3.1). Here is what I see on m

2018-11-06 18:35:53 -0600 commented question PNG encoding performance difference between 3.1 and 3.2

I found the commit which changed the timing: https://github.com/opencv/opencv/commit/1b22783d4636a74512171d67b95e6482f73

2018-11-02 18:37:38 -0600 edited question PNG encoding performance difference between 3.1 and 3.2

PNG encoding performance difference between 3.1 and master Encoding a PNG using OpenCV 3.2.0 takes about 2x longer than

2018-11-02 18:37:24 -0600 received badge  Editor (source)
2018-11-02 18:37:24 -0600 edited question PNG encoding performance difference between 3.1 and 3.2

PNG encoding performance difference between 3.1 and 3.2 Encoding a PNG using OpenCV 3.2.0 takes about 2x longer than Ope

2018-10-31 19:27:34 -0600 commented question PNG encoding performance difference between 3.1 and 3.2

The encode times using libraries built from the link hash (733fec0) look the same as version 3.2.0 (slower than 3.1). H

2018-10-31 18:14:37 -0600 asked a question PNG encoding performance difference between 3.1 and 3.2

PNG encoding performance difference between 3.1 and 3.2 Encoding a PNG using OpenCV 3.2.0 takes about 2x longer than Ope