我有一个程序尝试检测图像上的矩形物体(即太阳能模块)。为此,我将 c++ 与 opencv 3 和 Visual Studio 2015 Update 1 结合使用。
一般来说,我的程序使用 GaussianBlur
-> morphologyEx
-> Canny
-> HoughLines
-> findContours
-> approxPolyDP
。因为,我在寻找最佳参数时遇到问题,所以我尝试运行许多参数组合以获得最佳参数设置。
我遇到的问题是“在 Visual Studio 中调试”、“使用生成的 .exe 进行调试”、“在 Visual Studio 中发布”、“使用生成的 .exe 发布”之间得到不同的结果。另外,在其他计算机上运行 .exe 文件再次会更改结果。
在同一台机器上使用相同的设置运行程序不会改变结果(即它似乎是确定性的)。程序中也没有并发(除了opencv中有一些我不知道的)。
知道为什么不同设置之间存在如此巨大的不匹配(在一种设置中以 99% 的准确度检测太阳能模块的参数组合在另一种设置中根本无法检测到该模块)吗?
编辑:
我尝试创建一个最小的工作示例(见下文),其中包含代码,直到出现第一个不匹配(也许稍后会有更多不匹配)。我尝试初始化我找到的每个变量。
标识符paramterset
是一个对象的实例,其中包含我为找到最佳值而修改的所有参数。我检查了这些参数都已初始化并且在调试和释放中是相同的。
使用此代码,writeIntermediateResultImage
创建的前 3 个图像(基本上仅使用 opencv 方法 imwrite
并且仅指定图像存储的路径)是相同的但形态图像有所不同(根据一些online image comparer我发现有13.43%)。 一个区别是, Release模式下形态学图像的左边缘和上边缘的某些像素是黑色的,但图像内也存在其他差异。
编辑:似乎在 Release模式下使用生成的 .exe 文件运行代码时,根本不应用形态学算法,但图像只是向左和向下移动,在顶部和底部留下黑色边缘。
编辑:这种转变似乎取决于它运行的机器。在我的笔记本电脑上,我在没有应用形态的情况下进行了转变,而在我的台式机上,应用了形态,但没有转变和黑边。
void findSquares(const Mat& image, vector<vector<Point> >& squares, string srcName)
{
// 1) Get HSV channels
Mat firstStepResult(image.size(), CV_8U);
Mat hsvImage(image.size(), CV_8UC3);
// Convert to HSV space
cvtColor(image, hsvImage, CV_BGR2HSV);
writeIntermediateResultImage("HSV.jpg", hsvImage, srcName);
// Transform Value channel of HSV image to greyscale
Mat channel0Mat(image.size(), CV_8U);
Mat channel1Mat(image.size(), CV_8U);
Mat channel2Mat(image.size(), CV_8U);
Mat hsv_channels[3]{ channel0Mat, channel1Mat, channel2Mat };
split(hsvImage, hsv_channels);
firstStepResult = hsv_channels[parameterset.hsvChannel];
writeIntermediateResultImage("HSVChannelImage.jpg", firstStepResult, srcName);
// 2) Gaussian Denoising
Mat gaussImage = firstStepResult;
GaussianBlur(gaussImage, gaussImage, Size(parameterset.gaussKernelSize, parameterset.gaussKernelSize), 0, 0);
writeIntermediateResultImage("GaussianBlur.jpg", gaussImage, srcName);
// 3) Morphology
Mat morphologyImage = gaussImage;
morphologyEx(morphologyImage, morphologyImage, parameterset.morphologyOperator, Mat(parameterset.dilateKernelSize, parameterset.dilateKernelSize, 0), cv::Point(-1, -1), parameterset.numMorpholgies);
writeIntermediateResultImage("Morphology.jpg", morphologyImage, srcName);
}
我还检查了库路径,并且在正确的编译模式下使用了正确的库(使用“d”进行调试,不使用“发布”)。
最佳答案
我在代码中发现了错误,现在在每个配置中都得到了相同的结果。问题出在使用形态算子的行上。
morphologyEx(morphologyImage, morphologyImage, parameterset.morphologyOperator, Mat(parameterset.dilateKernelSize, parameterset.dilateKernelSize, 0), cv::Point(-1, -1), parameterset.numMorpholgies);
尽管创建的 Mat
对象 (Mat(parameterset.dilateKernelSize,parameterset.dilateKernelSize, 0)
) 在调试中充当结构元素,但它有点困惑发布中的一切。
使用
getStructuringElement(MORPH_RECT, Size(parameterset.dilateKernelSize, parameterset.dilateKernelSize))
因为结构元素起到了作用。
关于c++ - OpenCV 结果在调试/发布和其他机器上发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36797737/