用numpy将python转换为c++使用OpenCV

发布于 2025-01-26 07:55:12 字数 1433 浏览 2 评论 0原文

我正在研究一些Optimaz,并想将某些零件从Python转换为C ++

是否可以使用OpenCV将此代码转换为C ++?

Python代码使用numpy

import numpy as np
from PIL import Image

pil_img = Image.open(input_filename)
img = np.array(pil_img)
pixels = img.reshape((-1, 3))

num_pixels = pixels.shape[0]
num_samples = int(num_pixels*5)

idx = np.arange(num_pixels)
np.random.shuffle(idx)

samples = pixels[idx[:num_samples]]

更新

std::vector<uchar> sample_pixels(const cv::Mat& m, int sample_percent=5){
    assert(m.isContinuous());
    
    const auto* input = m.ptr<uchar>();
    
    int
        num_pixels      = m.total(),
        num_samples     = num_pixels * sample_percent;
    
    std::cout
        << "num pixels:  " << num_pixels << '\n'
        << "num samples: " << num_samples << '\n';
    
    std::vector<uchar> samples(num_samples);
    
    //  Fills idx with sequentially increasing values
    std::vector<int> idx(num_pixels);
    std::iota(idx.begin(), idx.end(), 0);
    
    //  Shuffle idx
    std::mt19937 engine(0);
    std::shuffle(idx.begin(), idx.end(), engine);
    
    for(int i = 0; i < num_samples; i++){
        //samples[i] = input[idx[i]];
    }
    
    //auto output_mat = cv::Mat(samples, false);
    //cv::imwrite("enhance-samples.png", output_mat);
    
    return samples;
}

I'm working on some optimazation and want to convert some parts from python to c++

Is it possible to convert this code to c++ with opencv?

The python code uses numpy

import numpy as np
from PIL import Image

pil_img = Image.open(input_filename)
img = np.array(pil_img)
pixels = img.reshape((-1, 3))

num_pixels = pixels.shape[0]
num_samples = int(num_pixels*5)

idx = np.arange(num_pixels)
np.random.shuffle(idx)

samples = pixels[idx[:num_samples]]

update

std::vector<uchar> sample_pixels(const cv::Mat& m, int sample_percent=5){
    assert(m.isContinuous());
    
    const auto* input = m.ptr<uchar>();
    
    int
        num_pixels      = m.total(),
        num_samples     = num_pixels * sample_percent;
    
    std::cout
        << "num pixels:  " << num_pixels << '\n'
        << "num samples: " << num_samples << '\n';
    
    std::vector<uchar> samples(num_samples);
    
    //  Fills idx with sequentially increasing values
    std::vector<int> idx(num_pixels);
    std::iota(idx.begin(), idx.end(), 0);
    
    //  Shuffle idx
    std::mt19937 engine(0);
    std::shuffle(idx.begin(), idx.end(), engine);
    
    for(int i = 0; i < num_samples; i++){
        //samples[i] = input[idx[i]];
    }
    
    //auto output_mat = cv::Mat(samples, false);
    //cv::imwrite("enhance-samples.png", output_mat);
    
    return samples;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彼岸花似海 2025-02-02 07:55:12

这是C ++ 11中的等效代码。这应该比您的Python代码快几倍。

#include <random>
#include <numeric>

#include <opencv2/opencv.hpp>

void shuffling(const std::string &input_filename, const std::string &output_filename) {

    // ========== UPDATE ==========
    const cv::Mat plain_input_mat = cv::imread(input_filename, -1);
    // Equivalent to img.reshape((-1, 3))
    const cv::Mat input_mat = plain_input_mat.reshape(3);
    // ============================

    // By doing this, you can access the pixels without any extra checks.
    assert(input_mat.isContinuous());
    const auto *input = input_mat.ptr<cv::Vec3b>();

    const auto num_samples = input_mat.total();
    std::vector<cv::Vec3b> output(num_samples);

    std::vector<int> idx(input_mat.total());
    std::iota(idx.begin(), idx.end(), 0);  // Equivalent to arange.

    // Note: numpy uses PCG64 which does not exist in the std library.
    std::mt19937 engine(0);
    std::shuffle(idx.begin(), idx.end(), engine);

    for (int i = 0; i < num_samples; i++) {
        output[i] = input[idx[i]];
    }

    // Save as an image if necessary.
    auto output_mat = cv::Mat(output, false);
    cv::imwrite(output_filename, output_mat);
}

还有一些其他笔记。

Note1:由于Python和STD之间的洗牌算法的差异,结果并不完全相同。

Note2:使用您的代码,num_samples不能大于输入图像中的像素数,这似乎是一个错误。请检查样本的长度

Note3:在两个实现中,最昂贵的部分是Shuffle。 Python的60%在这里花费了C ++的80%以上。如果您想进一步优化,这绝对是您应该利用的地方。

This is the equivalent code in C++11. This should be several times faster than your python code.

#include <random>
#include <numeric>

#include <opencv2/opencv.hpp>

void shuffling(const std::string &input_filename, const std::string &output_filename) {

    // ========== UPDATE ==========
    const cv::Mat plain_input_mat = cv::imread(input_filename, -1);
    // Equivalent to img.reshape((-1, 3))
    const cv::Mat input_mat = plain_input_mat.reshape(3);
    // ============================

    // By doing this, you can access the pixels without any extra checks.
    assert(input_mat.isContinuous());
    const auto *input = input_mat.ptr<cv::Vec3b>();

    const auto num_samples = input_mat.total();
    std::vector<cv::Vec3b> output(num_samples);

    std::vector<int> idx(input_mat.total());
    std::iota(idx.begin(), idx.end(), 0);  // Equivalent to arange.

    // Note: numpy uses PCG64 which does not exist in the std library.
    std::mt19937 engine(0);
    std::shuffle(idx.begin(), idx.end(), engine);

    for (int i = 0; i < num_samples; i++) {
        output[i] = input[idx[i]];
    }

    // Save as an image if necessary.
    auto output_mat = cv::Mat(output, false);
    cv::imwrite(output_filename, output_mat);
}

There are a couple of additional notes.

Note1: Due to the difference in the shuffle algorithm between python and std, the results are not exactly the same.

Note2: With your code, num_samples cannot be larger than the number of pixels in the input image, which seems to be a bug. Please check the length of the samples.

Note3: In both implementations, the most expensive part is shuffle. 60% for python and more than 80% for C++ is spent here. If you want to optimize further, this is definitely where you should exploit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文