开发者

Python 调用 C++ 传递numpy 数据详情

开发者 https://www.devze.com 2022-12-14 10:21 出处:网络 作者: darkerJ
目录1.C++ 代码2.python 代码1.C++ 代码 Demo.h #pragma once void GeneratorGaussKernel(int ksize, float sigma, float* kernel);
目录
  • 1.C++ 代码
  • 2.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 khhttp://www.cppcns.com);

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]);
  }


  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_m128, kw);
    }

  }

  if (filterKernel_m128) {
    _mm_free(filterKernel_m128);
    filterKernel_m128 = NULL;
  }
}

#endif
void SaltAndPepperFloat(float* in, float* out, int width, int height, float minV, float maxV, float proportion)
{
  int coordNumber = (int)(width * height * proportion);

  if (in != out) {
    memcpy_s(out, width * height * 3 * sizeof(float), in, width * height * 3 * sizeof(float));
  }

  for (int i = 0; i < coordNumber; ++i) {
    ImageCoord coord = gRandom.RandomImageCoord(width, height);
    bool saltOrPepper = gRandom.RandomBoolean();
    float value = saltOrPepper ? minV : maxV;
    int x = coord.x;
    int y = coord.y;
    int offset = (y * width + x) * 3;
    for (int c = 0; c < 3; ++c) {
      out[offset + c] = value;
    }
  }
}

void SaltAndPepperUInt8(unsigned char* in, unsigned char* out, int width, int height, float minV, float maxV, float proportion)
{
  int coordNumber = (int)(width * height * proportion);

  if (in != out) {
    memcpy_s(out, width * height * 3 * sizeof(unsigned char), in, width * height * 3 * sizeof(unsigned char));
  }
  for (int i = 0; i < coordNumber; ++i) {
    ImageCoord coord = gRandom.RandomImageCoord(width, height);
    bool saltOrPepper = gRandom.RandomBoolean();
    float value = saltOrPepper ? minV : maxV;
    int x = coord.x;
    int y = coord.y;
    int offset = (y * width + x) * 3;
    for (int c = 0; c < 3; ++c) {
      out[offset + c] = (unsigned char)value;
    }
  }
}

void ImageMinMax(float* in, int width, int height, int channels, float* minV, float* maxV)
{
  float minValue = 99999.f;
  float maxValue = -minValue;
  int number = width * height * channels;
  for (int i = 0; i < number; ++i) {
    float value = in[i];
    if (value > maxValue) {
      maxValue = value;
    }
    if (value < minValue) {
      minValue = value;
    }
  }
  *minV = (float)minValue;
  *maxV = (float)maxValue;
}

void ImageMinMax(unsigned char* in, int width, int height, int channels, unsigned char* minV, unsigned char* maxV)
{
  int minValue = 256;
  int maxValue = -1;
  int number = width * height * channels;
  for (int i = 0; i < number; ++i) {
    int value = in[i];
    if (value > maxValue) {
      maxValue = value;
    }
    if (value < minValue) {
      minValue = value;
    }
  }
  *minV = (unsigned char)minValue;
  *maxV = (unsigned char)maxValue;
}

void ImageMulAAddBFloatFloat(float* in, float* out, int width, int height, int channels, float A, float B)
{
  int size = width * height * channels;
  for (int i = 0; i < size; ++i) {
    out[i] = in[i] * A + B;
  }
}

void ImageMulAAddBUInt8UInt8(unsigned char* in, unsigned char* out, int width, int height, int channels, float A, float B)
{
#define ALVACLAMP(x, minV, maxV) \
    (x) < (minV) ? (minV) : ((x) > (maxV) ? (maxV) : (x))
  int size = width * height * channels;
  for (int i = 0; i < size; ++i) {
    out[i] = (unsigned char)(ALVACLAMP(in[i] * A + B, 0, 255));
  }
#undef ALVACLAMP
}

void ImageMulAAddBUInt8Float(unsigned char* in, float* out, int width, int height, int channels, float A, float B)
{
  int size = width * height * channels;
  for (int i = 0; i < size; ++i) {
    out[i] = in[i] * A + B;
  }
}

void NormalizeUInt8Float(unsigned char* in, float* out, int width, int height, int channels, int type)
{
  unsigned char minV, maxV;
  ImageMinMax(in, width, height, channels, &minV, &maxV);
  int size = width * height * channels;
  float inv = 1.f / (maxV - minV);
  float offset = 0.f;
  if (type == 1) {
    inv *= 2.f;
    offset = -1.f;
  }
  for (int i = 0; i < size; ++i) {
    out[i] = (in[i] - minV) * inv + offset;
  }
}

void NormalizeFloatFloat(float* in, float* out, int width, int height, int channels, int type)
{
  float minV, maxV;
  ImageMinMax(in, width, height, channels, &minV, &maxV);
  int size = width * height * channels;
  float inv = 1.f / (maxV - minV);
  float offset = 0.f;
  if (type == 1) {
    inv *= 2.f;
    offset = -1.f;
  }
  for (int i = 0; i < size; ++i) {
    out[i] = (in[i] - minV) * inv + offset;
  }
}

void RGBAvgUInt8Float(unsigned char* in, float* out, int width, int height)
{
  int size = width * height;
  for (int i = 0; i < size; ++i) {
    float avg = (in[i * 3 + 0] + in[i * 3 + 1] + in[i * 3 + 2]) / 3.f;
    out[i * 3 + 0] = avg;
    out[i * 3 + 1] = avg;
    out[i * 3 + 2] = avg;
  }
}

void RGBAvgFloatFloat(float* in, float* out, int width, int height)
{
  int size = width * height;
  for (int i = 0; i < size; ++i) {
    float avg = (in[i * 3 + 0] + in[i * 3 + 1] + in[i * 3 + 2]) / 3.f;
    out[i * 3 + 0] = avg;
    out[i * 3 + 1] = avg;
    out[i * 3 + 2] = avg;
  }
}

static PyObject* GeneratorGaussKernel(PyObject* self, PyObject* args) {
  //int ksize, float sigma, float* kernel
  PyObject* pyobj_filter = NULL;
  int ksize;
  float sigma;
  int ret = PyArg_ParseTuple(args, "Oif", &pyobj_filter, &ksize, &sigma);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_filter;

  float* data = (float*)(oarr->data);

  GeneratorGaussKernel(ksize, sigma, data);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* LeftAndRightMirrorImageUInt8(PyObject* self, PyObject* args) {
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
 int ret = PyArg_ParseTuple(args, "OOii", &pyobj_img, &pyobj_out_img, &width, &height);
  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;

  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  unsigned char* dataIn = (unsigned char*)(oarr->data);
  unsigned char* dataOut = (unsigned char*)(oarr_out->data);
 
  LeftAndRightMirrorImageUInt8(dataIn, dataOut, width, height);

  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;

  //std::cout << "";
}

static PyObject* LeftAndRightMirrorImageFloat(PyObject* self, PyObject* args) {

  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
  int ret = PyArg_ParseTuple(args, "OOii", &pyobj_img, &pyobj_out_img, &width, &height);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;

  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  float* dataIn = (float*)(oarr->data);  
  float* dataOut = (float*)(oarr_out->data);

  LeftAndRightMirrorImageFloat(dataIn, dataOut, width, height);

  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* UpAndDownMirrorImageUInt8(PyObject* self, PyObject* args) {

  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
  int ret = PyArg_ParseTuple(args, "OOii", &pyobj_img, &pyobj_out_img, &width, &height);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;

  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  unsigned char* dataIn = (unsigned char*)(oarr->data);

  unsigned char* dataOut = (unsigned char*)(oarr_out->data);

  UpAndDownMirrorImageUInt8(dataIn, dataOut, width, height);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* UpAndDownMirrorImageFloat(PyObject* self, PyObject* args) {

  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
  int ret = PyArg_ParseTuple(args, "OOii", &pyobj_img, &pyobj_out_img, &width, &height);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;

  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  float* dataIn = (float*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  UpAndDownMirrorImageFloat(dataIn, dataOut, width, height);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* ImageFilterFloat(PyObject* self, PyObject* args) {
  //float* in, float* out, int width, int height, float* filterKernel, int kw, int kh
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  PyObject* pyobj_filterKernel = NULL;
  int width, height;
  int kw, kh;
  int ret = PyArg_ParseTuple(args, "OOiiOii", &pyobj_img, &pyobj_out_img, &width, &height, &pyobj_filterKernel, &kw, &kh);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;
  PyArrayObject* kernel = (PyArrayObject*)pyobj_filterKernel;

  float* dataIn = (float*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);
  float* filter = (float*)(kernel->data);

  ImageFilterFloat(dataIn, dataOut, width, height, filter, kw, kh);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* SaltAndPepperFloat(PyObject* self, PyObject* args) {
  //float* in, float* out, int width, int height, float minV, float maxV, float proportion
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
  float minV, maxV, proportion;
  int ret = PyArg_ParseTuple(args, "OOiifff", &pyobj_img, &pyobj_out_img, &width, &height, &minV, &maxV, &proportion);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  float* dataIn = (float*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  SaltAndPepperFloat(da编程客栈taIn, dataOut, width, height, minV, maxV, proportion);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* SaltAndPepperUInt8(PyObject* self, PyObject* args) {
  //float* in, float* out, int width, int height, float minV, float maxV, float proportion
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
  float minV, maxV, proportion;
  int ret = PyArg_ParseTuple(args, "OOiifff", &pyobj_img, &pyobj_out_img, &width, &height, &minV, &maxV, &proportion);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  unsigned char* dataIn = (unsigned char*)(oarr->data);
  unsigned char* dataOut = (unsigned char*)(oarr_out->data);

  SaltAndPepperUInt8(dataIn, dataOut, width, height, minV, maxV, proportion);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* ImageMulAAddBFloatFloat(PyObject* self, PyObject* args) {
  //float* in, float* out, int width, int height, int channels, float A, float B
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height, channels = 3;
  float A, B;
  int ret = PyArg_ParseTuple(args, "OOiiff", &pyobj_img, &pyobj_out_img, &width, &height, &A, &B);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  float* dataIn = (float*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  ImageMulAAddBFloatFloat(dataIn, dataOut, width, height, channels, A, B);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* ImageMulAAddBUInt8Float(PyObject* self, PyObject* args) {
  //float* in, float* out, int width, int height, int channels, float A, float B
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height, channels = 3;
  float A, B;
  int ret = PyArg_ParseTuple(args, "OOiiff", &pyobj_img, &pyobj_out_img, &width, &height, &A, &B);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  unsigned char* dataIn = (unsigned char*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  ImageMulAAddBUInt8Float(dataIn, dataOut, width, height, channels, A, B);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* ImageMulAAddBUInt8UInt8(PyObject* self, PyObject* args) {
  //float* in, float* out, int width, int height, int channels, float A, float B
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height, channels = 3;
  float A, B;
  int ret = PyArg_ParseTuple(args, "OOiiff", &pyobj_http://www.cppcns.comimg, &pyobj_out_img, &width, &height, &A, &B);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  unsigned char* dataIn = (unsigned char*)(oarr->data);
  unsigned char* dataOut = (unsigned char*)(oarr_out->data);

  ImageMulAAddBUInt8UInt8(dataIn, dataOut, width, height, channels, A, B);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* NormalizeUInt8Float(PyObject* self, PyObject* args) {
  // unsigned char* in, float* out, int width, int height, int channels, int type
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height, channels = 3;
  int type;
  int ret = PyArg_ParseTuple(args, "OOiii", &pyobj_img, &pyobj_out_img, &width, &height, &type);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  unsigned char* dataIn = (unsigned char*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  NormalizeUInt8Float(dataIn, dataOut, width, height, channels, type);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* NormalizeFloatFloat(PyObject* self, PyObject* args) {
  // unsigned char* in, float* out, int width, int height, int channels, int type
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height, channels = 3;
  int type;
  int ret = PyArg_ParseTuple(args, "OOiii", &pyobj_img, &pyobj_out_img, &width, &height, &type);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  float* dataIn = (float*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  NormalizeFloatFloat(dataIn, dataOut, width, height, channels, type);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* RGBAvgUInt8Float(PyObject* self, PyObject* args) {
  // unsigned char* in, float* out, int width, int height
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
  int ret = PyArg_ParseTuple(args, "OOii", &pyobj_img, &pyobj_out_img, &width, &height);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  unsigned char* dataIn = (unsigned char*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  RGBAvgUInt8Float(dataIn, dataOut, width, height);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyObject* RGBAvgFloatFloat(PyObject* self, PyObject* args) {
  // unsigned char* in, float* out, int width, int height
  PyObject* pyobj_img = NULL;
  PyObject* pyobj_out_img = NULL;
  int width, height;
  inhttp://www.cppcns.comt ret = PyArg_ParseTuple(args, "OOii", &pyobj_img, &pyobj_out_img, &width, &height);

  PyArrayObject* oarr = (PyArrayObject*)pyobj_img;
  PyArrayObject* oarr_out = (PyArrayObject*)pyobj_out_img;

  float* dataIn = (float*)(oarr->data);
  float* dataOut = (float*)(oarr_out->data);

  RGBAvgFloatFloat(dataIn, dataOut, width, height);
  PyObject* result = PyUnicode_FromFormat("result:%s", "ok");
  return result;
}

static PyMethodDef DemoMethods[] = {
  {"LeftAndRightMirrorImageUInt8", (PyCFunction)LeftAndRightMirrorImageUInt8, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"LeftAndRightMirrorImageFloat", (PyCFunction)LeftAndRightMirrorImageFloat, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"UpAndDownMirrorImageUInt8", (PyCFunction)UpAndDownMirrorImageUInt8, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"UpAndDownMirrorImageFloat", (PyCFunction)UpAndDownMirrorImageFloat, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"ImageFilterFloat", (PyCFunction)ImageFilterFloat, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"SaltAndPepperFloat", (PyCFunction)SaltAndPepperFloat, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"SaltAndPepperUInt8", (PyCFunction)SaltAndPepperUInt8, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"ImageMulAAddBFloatFloat", (PyCFunction)ImageMulAAddBFloatFloat, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"ImageMulAAddBUInt8Float", (PyCFunction)ImageMulAAddBUInt8Float, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"ImageMulAAddBUInt8UInt8", (PyCFunction)ImageMulAAddBUInt8UInt8, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"NormalizeUInt8Float", (PyCFunction)NormalizeUInt8Float, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"NormalizeFloatFloat", (PyCFunction)NormalizeFloatFloat, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"RGBAvgUInt8Float", (PyCFunction)RGBAvgUInt8Float, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"RGBAvgFloatFloat", (PyCFunction)RGBAvgFloatFloat, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {"GeneratorGaussKernel", (PyCFunction)GeneratorGaussKernel, METH_VARARGS | METH_KEYWORDS, "I guess here is description." },
  {NULL, NULL, 0, NULL}
};

static struct PyModuleDef demoModule = {
  PyModuleDef_HEAD_INIT,
  "mirror",
  NULL,
  -1,
  DemoMethods
};

PyMODINIT_FUNC
PyInit_ImgProcessing(void) { // ImgProcessing 为生成的dll名称
  return PyModule_Create(&demoModule);
}

2.Python 代码

把C++ 编译出的ImgProcessing.dll 改为 ImgProcessing.pyd 并 拷贝到Python工程下

# -*- coding:utf-8 -*-
import cv2
import random
import numpy as np
import ImgProcessing as aug


class AugmentImagesBase:
  def _gauss(self, x, y, sigma=1.):
    Z = 2 * np.pi * sigma ** 2
    kernel_value = 1 / Z * np.exp(-(x ** 2 + y ** 2) / 2 / sigma ** 2)
    return kernel_value

  def _gauss_kernel(self, kwidth, kheight, kchannel=1):
    kernels = np.zeros((kheight, kwidth, kchannel, 1), np.float32)
    mid = np.floor(kwidth / 2)
    for kernel_idx in range(kchannel):
      for i in range(kheight):
        for j in range(kwidth):
          kernels[i, j, kernel_idx, 0] = self._gauss(i - mid, j - mid)
    if kchannel == 1:
      kernels = np.reshape(kernels, (kheight, kwidth))
    return kernels

  def left_right_flip(self, img_in, img_out, width=336, height=192):
    aug.AlvaLeftAndRightMirrorImageUInt8(img_in, img_out, width, height)
    return img_out

  def up_down_flip(self, img_in, img_out, width=336, height=192):
    aug.AlvaUpAndDownMirrorImageUInt8(img_in, img_out, width, height)
    return img_out

  def filtering(self, img_in, img_out, width=336, height=192, kernel=None, kwidth=3, kheight=3):
    aug.AlvaImageFilterFloat(img_in, img_out, width, height, kernel, kwidth, kheight)
    return img_out

  def pepper_salt(self, img_in, img_out, width=336, height=192, min_v=0, max_v=255, proportion=0.1):
    rand_proportion = random.uniform(0., proportion)
    aug.AlvaSaltAndPepperUInt8(img_in, img_out, width, height, min_v, max_v, rand_proportion)
    return img_out

  def contrast(self, img_in, img_out, width=336, height=192, a=0.6, b=0.4):
    aug.AlvaImageMulAAddBUInt8UInt8(img_in, img_out, width, height, a, b)
    return img_out

  def average_rgb(self, img_in, img_out, width=336, height=192):
    img_in = img_in.astype(np.float32)
    img_out = img_out.astype(np.float32)
    aug.AlvaRGBAvgFloatFloat(img_in, img_out, width, height)
    img_out = img_out.astype(np.uint8)
    return img_out

  def normalize(self, img_in, img_out, width=336, height=192, type=1):
    aug.AlvaNormalizeUInt8Float(img_in, img_out, width, height, type)
    return img_out

  def normal(self, img_in, img_out):
    return img_in

  def rota_180(self, img_in, img_out):
    return cv2.rotate(img_in, cv2.ROTATE_180)

  def rand_aug(self, img_in):
    img_in = np.asarray(img_in, dtype=np.uint8)
    img_out = np.ones_like(img_in).astype(np.uint8)
    aug_func = {
      "left_right_flip": self.left_right_flip,
      'up_down_flip': self.up_down_flip,
      'pepper_salt': self.pepper_salt,
      'contrast': self.contrast,
      'average_rgb': self.average_rgb,
      "normal": self.normal,
      "rota_180": self.rota_180,
    }
    img_out_curr = np.ones_like(img_in[0]).astype(np.uint8)
    aug_names = []
    for i in range(img_in.shape[0]):
      aug_name = random.sample(list(aug_func.keys()), 1)[0]
      img_out_curr = aug_func[aug_name](np.squeeze(img_in[i]), img_out_curr)
      img_out[i] = img_out_curr
      aug_names.append(aug_name)
    return img_out, aug_names


def image_aug(img_path):
  import cv2
  import time
  aug_tools = AugmentImagesBase()
  kernel = aug_tools._gauss_kernel(5, 5)
  img_in = cv2.imread(img_path).astype(np.float32)
  img_out = np.ones_like(img_in).astype(np.float32)
  time1 = time.time()
  for i in range(1000):
    # img_out, aug_names = aug_tools.average_rgb(img_in, img_out)
    img_out = aug_tools.filtering(img_in, img_out, kernel=kernel, kwidth=5, kheight=5)

  time2 = time.time()
  print("end time:", time2 - time1)
  # cv2.imshow(aug_names[0], img_out[0])
  cv2.imshow("aug img", img_out.astype(np.uint8))
  cv2.imshow('src img', img_in.astype(np.uint8))
  cv2.waitKey(0)


if __name__ == "__main__":
  img_path = r"G:\20210917\img\1.jpg"
  image_aug(img_path)

PyArg_ParseTuple 的使用见:PyArg_ParseTuple

到此这篇关于Python 调用 C++ 传递numpy 数据详情的文章就介绍到这了,更多相关Python调用 C++内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号