版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/PinkRiverside/article/details/72615077
對OpenCV 3.1.0 SVM輪廓特徵的提取和分類 I中提取到的輪廓使用OpenCV中的SVM進行分類。
首先對這些輪廓進行裁剪:
Mat getROI(Mat &src){
int left, right, top, bottom;
left = src.cols;
right = 0;
top = src.rows;
bottom = 0;
//得到區域
for (int i = 0; i<src.rows; i++)
{
for (int j = 0; j<src.cols; j++)
{
if (src.at<uchar>(i, j) > 0)
{
if (j<left) left = j;
if (j>right) right = j;
if (i<top) top = i;
if (i>bottom) bottom = i;
}
}
}
cout << "rows:" << src.rows << ",cols:" <<src.cols<< endl;
cout << "left:" << left << ",right:" << right << ",top:" << top << ",bottom:"<<bottom<<endl;
imshow("b", src);
Mat dst(bottom - top, right - left, CV_8UC1);
for (int j = 0; j < bottom - top; j++){
for (int k = 0; k < right - left; k++){
dst.at<uchar>(j, k) ='0';
}
}
cout << right - left << " "<<(int)src.at<uchar>(bottom , right) << endl;
cout << bottom - top << endl;
for (int j = 0; j < bottom - top; j++){
for (int k = 0; k < right - left; k++){
dst.at<uchar>(j, k) = src.at<uchar>(j+top, k+left);
}
}
cout << "left:" << left << ",right:" << right << ",top:" << top << ",bottom:" << bottom << endl;
imshow("a", dst);
return dst;
}
將裁剪後的區域縮放至16*16的大小,準備樣本數據並進行訓練。
int main(int argc, char** argv)
{
//訓練數據的分類 1.0蘋果-1.0香蕉
int labels[8] = { 1,1,1,1,-1,-1,-1,-1 };
Mat labelsMat(8, 1, CV_32SC1, labels);
//訓練數據矩陣
float colors[8][16*16];
//蘋果樣本數據
for (int i = 0; i < 4; i++){
char name[30];
sprintf(name, "appleCanny/apple%d.jpg", i);
Mat src = imread(name,-1);
Mat tmp = getROI(src);
Mat dst(16, 16, CV_8UC1);
resize(tmp, dst, dst.size());
for (int j = 0; j < 16; j++){
for (int k = 0; k < 16; k++){
colors[i][j*16+k] = dst.at<uchar>(j, k);
}
}
}
//香蕉樣本數據
for (int i = 0; i < 4; i++){
char name[30];
sprintf(name, "bananaCanny/banana%d.jpg", i);
Mat src = imread(name, -1);
Mat tmp = getROI(src);
Mat dst(16, 16, CV_8UC1);
resize(tmp, dst, dst.size());
for (int j = 0; j < 16; j++){
for (int k = 0; k < 16; k++){
colors[i+4][j * 16 + k] = dst.at<uchar>(j, k);
}
}
}
Mat trainingDataMat(8, 16*16, CV_32FC1, colors);
//初始化SVM
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::Types::C_SVC);
svm->setKernel(SVM::KernelTypes::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
//訓練
svm->train(trainingDataMat,SampleTypes::ROW_SAMPLE , labelsMat);
//保存訓練數據
svm->save("SVM_CANNY_DATA.xml");
waitKey();
return 0;
}