OpenCV 3.2.0:读取 Canny 图像以训练 SVM

Posted

技术标签:

【中文标题】OpenCV 3.2.0:读取 Canny 图像以训练 SVM【英文标题】:OpenCV 3.2.0: Reading Canny image for training SVM 【发布时间】:2017-01-30 10:20:30 【问题描述】:

我在读取用于训练 SVM 的边缘图像时遇到问题:

int numFiles = 1;
int imgArea = 60 * 60; //canny image size
Mat trainingMat(numFiles, imgArea, CV_32FC1);// or  CV_8UC3

Mat imgMat = imread("C://canny.jpg");
int ii = 0; // Current column in trainingMat
for (int i = 0; i<imgMat.rows; i++) 
    for (int j = 0; j < imgMat.cols; j++) 
        trainingMat.at<float>(numFiles, ii++) = imgMat.at<uchar>(i, j); --> here the error
    

Mat labels(numFiles, 1, CV_32FC1);

Ptr<ml::SVM> svm = ml::SVM::create();
svm->setType(ml::SVM::C_SVC);
svm->setKernel(ml::SVM::LINEAR);
svm->setGamma(3);

svm->train(trainingMat, ml::ROW_SAMPLE, labels);
svm->save("svm_filename");
svm->load("svm_filename");

//test image using the trained svm
Mat imgMatTest = imread("C://canny1.jpg");
svm->predict(imgMatTest);

我遇到的异常:

trainingMat.at<float>(numFiles, ii++) = imgMat.at<uchar>(i, j);

test.exe 中 0x000007FEFCE4A06D 处未处理的异常:Microsoft C++ 异常:内存位置 0x000000000015F300 处的 cv::Exception。

指的是:

CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);

我也尝试过使用“uchar”,但遇到了同样的异常。有人可以指导我如何解决这个问题,以及在修复当前代码后是否会在其余代码中出现更多问题?

【问题讨论】:

Mat trainingMat(numFiles, imgArea, CV_8UC3); 不应该是CV_32FC1,因为您使用.at&lt;float&gt; 访问它的值? @Miki 在使用 CV_32FC1 时也会出现同样的异常! 您将imgMat 加载为CV_8UC3。使用Mat imgMat = imread("C://canny.jpg", IMREAD_GRAYSCALE); 将其作为CV_8UC1 引导。我建议研究一下cv::Mat 【参考方案1】:

问题在于 imgMat 是 CV_8UC3 类型(无论它是否真的有颜色)。

当您使用 imgMat.at 访问 imgMat 时,访问方法需要一个 CV_8UC1,但事实并非如此。

在循环之前,将图像转换为灰度,它应该不会崩溃。

cv::Mat gray;
cv::cvtColor(imgMat, gray, CV_BGR2GRAY);

【讨论】:

以上是关于OpenCV 3.2.0:读取 Canny 图像以训练 SVM的主要内容,如果未能解决你的问题,请参考以下文章

opencv简单的图像处理

OpenCV中的图像处理 —— 图像梯度+Canny边缘检测+图像金字塔

OpenCV小项目:自实现 Canny 算子

opencv 检测图像边缘 Canny算法应用

OpenCV——Canny边缘检测

python使用openCV图像加载(转化为灰度图像)Canny边缘检测器检测图像的边缘(Detect Edges)