Python调用 C++
darkerJ 人气:01.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]); } 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(dataIn, 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_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); 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; 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); 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
加载全部内容