gpt4 book ai didi

c# - 包装 OpenCv C++ 代码以在 C# 中使用

转载 作者:太空狗 更新时间:2023-10-29 22:59:49 31 4
gpt4 key购买 nike

我正在尝试包装 C++使用 OpenCv 的类这样我就可以在 C# 中使用它.

我有 C++功能:

void ImageBrightener::BrightenImage(const cv::Mat& sourceImage, cv::Mat& targetImage, int maxTarget)
{
double scaleFactor;
double shiftFactor = 0;
double minVal = DBL_MAX, minValTemp;
double maxVal = -DBL_MAX, maxValTemp;
auto numPixels = 0;
const auto RANGE_TOP_EXTEND = 10;
const auto RANGE_BOTTOM_EXTEND = 7;

assert(sourceImage.type() == CV_8UC1);
assert(sourceImage.channels() == 1);

cv::minMaxIdx(sourceImage, &minValTemp, &maxValTemp);
if (minValTemp < minVal)
minVal = minValTemp;
if (maxValTemp>maxVal)
maxVal = maxValTemp;

numPixels += sourceImage.cols * sourceImage.rows;

if (maxVal == minVal)
{
sourceImage.convertTo(targetImage, CV_8UC1, 1, shiftFactor);
return;
}

// Account for prev/curr ROI differences - add a bit to the range
maxVal += RANGE_TOP_EXTEND;
minVal -= RANGE_BOTTOM_EXTEND;
minVal = std::max(minVal, 0.);

if ((maxVal - minVal) < maxTarget)
{
scaleFactor = maxTarget / (maxVal - minVal);
shiftFactor = -1 * scaleFactor * minVal;

sourceImage.convertTo(targetImage, CV_8UC1, scaleFactor, shiftFactor);
return;
}

auto fltMinVal = static_cast<float>(minVal) - 1;
auto fltMaxVal = static_cast<float>(maxVal) + 1;

// Check histogram
const unsigned int *currval;

#define BINS (100)
#define CUTOFF (0.00003)
#define RESCUTOFF (0.2)

int hist[BINS] = { 0 };
int bin;

numPixels += sourceImage.cols * sourceImage.rows;
for (auto rowIndex = 0; rowIndex < sourceImage.rows; rowIndex++)
{
currval = sourceImage.ptr<unsigned>(rowIndex, 0);
for (auto colIndex = 0; colIndex < sourceImage.cols; colIndex++)
{
bin = static_cast<int>((BINS - 1) * ((*currval - fltMinVal) / (fltMaxVal - fltMinVal)));
assert(bin >= 0 && bin < BINS);
hist[bin]++;
++currval;
}
}

double ratio;
auto sum = 0;
int i;
for (i = BINS - 1; i >= 0; i--)
{
sum += hist[i];
ratio = static_cast<double>(sum) / static_cast<double>(numPixels);
if (ratio > CUTOFF)
break;
}
if (static_cast<double>(BINS - i) / static_cast<double>(BINS) > RESCUTOFF)
fltMaxVal = fltMinVal + ((i + 2)*(fltMaxVal - fltMinVal)) / BINS;

// Account for prev/curr ROI differences - add a bit to the range
fltMaxVal += RANGE_TOP_EXTEND;
fltMinVal -= RANGE_BOTTOM_EXTEND;
fltMinVal = std::max(fltMinVal, 0.f);

scaleFactor = maxTarget / (fltMaxVal - fltMinVal);
shiftFactor = -1 * scaleFactor * fltMinVal;

sourceImage.convertTo(targetImage, CV_8UC1, scaleFactor, shiftFactor);
}

当我使用以下 C++ 测试此代码时代码:

int main()
{
auto* m_imageBrightener = new ImageBrightener();
auto inputImage = cv::imread("E:\\ttt.png", CV_LOAD_IMAGE_UNCHANGED);

cv::Mat outputImage;

m_imageBrightener->BrightenImage(inputImage, outputImage, 2000);
cv::imwrite("E:\\new_ttt.png", outputImage);
}

一切正常,代码做了它应该做的事情,即获得一个深色的 8 位图像,并将其调亮(我尝试用 500 替换 200 - 它工作正常)。 new_ttt.png图像按预期变亮。

另一方面,我有以下 /Clr代码,它包装了 C++代码并创建一个 DLL从中:

array<System::Byte>^ ImageProcessing::ImageBrightenerWrapper::BrightenImage(array<System::Byte>^ sourceImage, int imageWidth, int imageHeight, int maxTarget)
{
array<System::Byte>^ targetImage = (array<System::Byte>^)sourceImage->Clone();

pin_ptr<System::Byte> sourcePointer = &sourceImage[0];
pin_ptr<System::Byte> targetPointer = &targetImage[0];

cv::Mat sourceMat(imageHeight, imageWidth, CV_8UC1, (unsigned short*)sourcePointer);
cv::Mat targetMat(imageHeight, imageWidth, CV_8UC1, (unsigned short*)targetPointer);

targetMat.setTo(0);
m_imageBrightener->BrightenImage(sourceMat, targetMat, maxTarget);

uchar* tempPointer;
for (auto rowIndex = 0; rowIndex < imageHeight; ++rowIndex)
{
tempPointer = targetMat.ptr<uchar>(rowIndex);
for (auto colIndex = 0; colIndex < imageWidth; ++colIndex)
targetImage[rowIndex + colIndex] = tempPointer[colIndex];
}

return targetImage;
}

有了它,我还有一个WPF具有控制 maxTarget slider 的应用程序参数。

这就是我面临的问题:

1) 一方面,maxTarget 介于 0 和 960 之间的任何值使匹配 maxTarget / 2 的行索引变亮- 意思是,当我向右滑动 slider 以获得更大的值时,图像的一部分变亮,其余部分与原始图像一样。 (示例:如果 maxTarget 为 300,则第 0 行和第 150 行之间的所有行都将更亮,其余行将与原始行一样)。

2) 另一方面,如果我越过 maxTarget 的值 if 960|然后应用程序崩溃并出现以下错误(即使代码被 try/catch 包围):

“ImageBrightenerWrapper.dll 中出现类型为‘System.AccessViolationException’但未在用户代码中处理的异常。附加信息:尝试读取或写入 protected 内存。这通常表示其他内存正在运行腐败。”

我在这里做错了什么?

最佳答案

于是我找到了解决问题的两个主要问题:

1) 我错误地混合了 C# 代码中的参数顺序。

2) 我必须替换以下行:

cv::Mat sourceMat(imageHeight, imageWidth, CV_8UC1, (unsigned short*)sourcePointer);

有了这个:

cv::Mat sourceMat(imageHeight, imageWidth, CV_16UC1, (unsigned short*)sourcePointer);

关于c# - 包装 OpenCv C++ 代码以在 C# 中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35864267/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com