网站/小程序/APP个性化定制开发,二开,改版等服务,加扣:8582-36016

这篇文章主要介绍了Python 调用 C++ 传递numpy 数据详情,文章主要分为两部分,c++代码和python代码,代码分享详细,需要的小伙伴可以参考一下,希望对你有所帮助

 

1.C++ 代码

Demo.h

#pragma once
void GeneratorGaussKernel(int ksize, float sigma, float* kernel);

void LeftAndRightMirrorImageUInt8(unsigned char* in, unsigned char* out, int width, int height);

void LeftAndRightMirrorImageFloat(float* in, float* out, int width, int height);

void UpAndDownMirrorImageFloat(float* in, float* out, int width, int height);

void UpAndDownMirrorImageUInt8(unsigned char* in, unsigned char* out, int width, int height);
void ImageFilterFloat(float* in, float* out, int width, int height, float* filterKernel, int kw, int kh);

void SaltAndPepperFloat(float* in, float* out, int width, int height, float minV, float maxV, float proportion);

void SaltAndPepperUInt8(unsigned char* in, unsigned char* out, int width, int height, float minV, float maxV, float proportion);
void ImageMinMax(float* in, int width, int height, int channels, float* minV, float* maxV);

void ImageMinMax(unsigned char* in, int width, int height, int channels, unsigned char* minV, unsigned char* maxV);
void ImageMulAAddBFloatFloat(float* in, float* out, int width, int height, int channels, float A, float B);

void ImageMulAAddBUInt8UInt8(unsigned char* in, unsigned char* out, int width, int height, int channels, float A, float B);
void ImageMulAAddBUInt8Float(unsigned char* in, float* out, int width, int height, int channels, float A, float B);

void NormalizeUInt8Float(unsigned char* in, float* out, int width, int height, int channels, int type);
void NormalizeFloatFloat(float* in, float* out, int width, int height, int channels, int type);
void RGBAvgUInt8Float(unsigned char* in, float* out, int width, int height);
void RGBAvgFloatFloat(float* in, float* out, int width, int height);


Demo.cpp 

#include <Python.h>
#include <malloc.h>
#include <numpy/arrayobject.h>
#include <iostream>
#include <vector>
#include <xmmintrin.h>
#include <immintrin.h>
#include "omp.h"

class ImageCoord {
public:
    ImageCoord() {
        x = 0; y = 0;
    }

    ImageCoord(const ImageCoord& coord) {
        x = coord.x;
        y = coord.y;
    }
    ImageCoord(int x, int y) {
        this->x = x;
        this->y = y;
    }
    void operator= (ImageCoord& coord) {
        x = coord.x;
        y = coord.y;
    }

    int x, y;
};

class Random {
public:
    Random() {
        srand((unsigned int)time(NULL));
    }

    ImageCoord RandomImageCoord(int width, int height) {
        ImageCoord ans;
        ans.x = rand() % width;
        ans.y = rand() % height;
        return ans;
    }
    bool RandomBoolean() {
        return rand() % 2 == 1;
    }
};

static Random gRandom;

void GeneratorGaussKernel(int ksize, float sigma, float* kernel)
{
    int bufferSize = ksize * ksize;
    float sigmasigma2 = 2.0f * sigma * sigma;
    float sigmasigma2Inv = 1.f / sigmasigma2;
    float sigmasigma2PIInv = sigmasigma2Inv / 3.14159265358979f;
    int radius = ksize / 2;
    float sum = 0.f;
    for (int i = -radius; i <= radius; ++i) {
        for (int j = -radius; j <= radius; ++j) {
            kernel[(i + radius) * ksize + (j + radius)] = sigmasigma2PIInv * expf(-(i * i + j * j) * sigmasigma2Inv);
        }
    }

    for (int i = 0; i < bufferSize; ++i) {
        sum += kernel[i];
    }
    sum = 1.f / sum;
    for (int i = 0; i < bufferSize; ++i) {
        kernel[i] = kernel[i] * sum;
    }
}

void LeftAndRightMirrorImageUInt8(unsigned char* in, unsigned char* out, int width, int height)
{
    for (int i = 0; i < height; ++i) {
        int hoffset = i * width;
        for (int j = 0; j < width; ++j) {

            int woffset = (hoffset + j) * 3;
            int woffset_ = (hoffset + width - 1 - j) * 3;
            for (int n = 0; n < 3; ++n) {
                out[woffset_ + n] = in[woffset + n];
            }
        }
    }
}

void LeftAndRightMirrorImageFloat(float* in, float* out, int width, int height)
{
    for (int i = 0; i < height; ++i) {
        int hoffset = i * width;
        for (int j = 0; j < width; ++j) {
            int woffset = (hoffset + j) * 3;
            int woffset_ = (hoffset + width - 1 - j) * 3;
            for (int n = 0; n < 3; ++n) {
                out[woffset_ + n] = in[woffset + n];
            }
        }
    }
}

void UpAndDownMirrorImageFloat(float* in, float* out, int width, int height)
{
    int lineOffset = width * 3;
    int lineSize = lineOffset * sizeof(float);
    float* outTmp = out + lineOffset * height - lineOffset;
    float* inTmp = in;
    for (int i = 0; i < height; ++i) {
        memcpy_s(outTmp, lineSize, inTmp, lineSize);
        outTmp -= lineOffset;
        inTmp += lineOffset;
    }
}

void UpAndDownMirrorImageUInt8(unsigned char* in, unsigned char* out, int width, int height)
{
    int lineOffset = width * 3;
    int lineSize = lineOffset * sizeof(unsigned char);
    unsigned char* outTmp = out + lineOffset * height - lineOffset;
    unsigned char* inTmp = in;
    for (int i = 0; i < height; ++i) {
        memcpy_s(outTmp, lineSize, inTmp, lineSize);
        outTmp -= lineOffset;
        inTmp += lineOffset;
    }
}

#if 0

void Conv(float* in, float* out, int width, float* filter, int ksize) {

    int lineSize = width * 3;
    float* inTemp = in;
    float* outTemp = out;
    out[0] = 0.f; out[1] = 0.f; out[2] = 0.f;
    for (int i = 0; i < ksize; ++i) {
        for (int j = 0; j < ksize; ++j) {
            int xoffset = j * 3;
            out[0] += (*filter) * inTemp[xoffset + 0];
            out[1] += (*filter) * inTemp[xoffset + 1];
            out[2] += (*filter) * inTemp[xoffset + 2];
            filter++;
        }
        inTemp = inTemp + lineSize;
    }
}

void ImageFilterFloat(float* in, float* out, int width, int height, float* filterKernel, int kw, int kh)
{
    size_t size = (size_t)width * (size_t)height * sizeof(float) * 3;

    int startX = kw / 2;
    int endX = width - kw / 2;
    
    int startY = kh / 2;
    int endY = height - kh / 2;

    float* tempOut = out + (startY * width + startX) * 3;

    memset(out, 0, size);
    //memcpy_s(out, size, in, size);
    omp_set_num_threads(32);

#pragma omp parallel for
    for (int i = 0; i <= height - kh; ++i) {
        int yoffset = i * width * 3;
        for (int j = 0; j <= width - kw; ++j) {
            int xoffset = yoffset + j * 3;
            Conv((in + xoffset), (tempOut + xoffset), width, filterKernel, kw);
        }

    }
}
#elif 1

void Conv(float* in, float* out, int width, __m128* filter, int ksize) {

    int lineSize = width * 3;
    float* inTemp = in;
    float* outTemp = out;
    out[0] = 0.f; out[1] = 0.f; out[2] = 0.f;
    __m128 sum = _mm_set_ps1(0.f);
    for (int i = 0; i < ksize; ++i) {
        for (int j = 0; j < ksize; ++j) {
            int xoffset = j * 3;

            __m128 img_value = _mm_set_ps(1.f, inTemp[xoffset + 2], inTemp[xoffset + 1], inTemp[xoffset + 0]);

            sum = _mm_add_ps(_mm_mul_ps((*filter), img_value), sum);

            filter++;
        }
        inTemp = inTemp + lineSize;
    }
    out[0] = sum.m128_f32[0];
    out[1] = sum.m128_f32[1];
    out[2] = sum.m128_f32[2];
}

void ImageFilterFloat(float* in, float* out, int width, int height, float* filterKernel, int kw, int kh)
{
    size_t size = (size_t)width * (size_t)height * sizeof(float) * 3;

    int startX = kw / 2;
    int endX = width - kw / 2;

    int startY = kh / 2;
    int endY = height - kh / 2;

    float* tempOut = out + (startY * width + startX) * 3;

    memset(out, 0, size);

    __m128* filterKernel_m128 = (__m128*)_mm_malloc(kw * kh * sizeof(__m128), sizeof(__m128));
    for (int i = 0; i < kw * kh; ++i) {
        filterKernel_m128[i] = _mm_set_ps1(filterKernel[i]);
    }


 &nb                                                    

评论 0

暂无评论
0
0
0
立即
投稿
发表
评论
返回
顶部