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
发表评论 取消回复