//**************//**************//**************//**************//**************//**************//
//**************//**************//**************//**************//**************//**************//
//**************//**************//**************//**************//**************//**************//
//**************//**************//**************//**************//**************//**************//
//************** //**************//
//************** 以下代码由厦门大学陈默含提供,如需使用,记得说声谢谢,嗯 //**************//
//************** //**************//
//**************//**************//**************//**************//**************//**************//
//**************//**************//**************//**************//**************//**************//
//**************//**************//**************//**************//**************//**************//
//**************//**************//**************//**************//**************//**************//
#include "StdAfx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <vector>
#include<ppl.h>
using namespace cv;
using namespace std;
using namespace concurrency;
#define WINDOW_NAME "[程序窗口]"
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<stdio.h>
#include <mutex>
void imrotate(Mat& img, Mat& newIm, double angle);
void on_mouse(int EVENT, int x, int y, int flags, void* userdata);
void CreateScaledShapeModel(Mat Template, int PyrLevel, int AngleStart, int AngleExtent, int AngleStep, float ScaleMin, float ScaleMax, float ScaleStep, \
vector<Mat>* pModelImageSet, vector<int>* pModelPointSet, vector<float>* pScaleSet, vector<float>* pAngleSet);
void FindScaledShapeModel(Mat Image, vector<Mat> ModelImageSet, vector<int> ModelPointSet, vector<float> ScaleSet, vector<float> AngleSet, int PyrLevel, float MinScore, \
vector<int>* pRow, vector<int> * pCol, vector<float>* pScale, vector<float>* pAngle, vector<float>* pScore);
int main()
{
//缩放参数
float scaleMin = 0.9, scaleMax = 1.1, scaleStep = 0.1;
//角度参数
float angleStart = 0, angleExtent = 330, angleStep = 15;
//金字塔层数,规定在多大的金字塔图中搜索,数字越大,图片越小,搜索越快
int pyrLevel = 2;
//最小得分限制
float minScore = 0.6;
//生成模版集合
vector<float> scaleSet;
vector<float> angleSet;
vector<Mat> modelImageSet;
vector<int> modelPointSet;
vector<int> row, col;
vector<float> scale, angle, score;
//待检测图片
//Mat srcImage = imread("img/a.png");
Mat srcImage=imread("img/5.png");
Mat cannysrcImage, tempsrcImage;
blur(srcImage, srcImage,Size(3,3) );
Canny(srcImage, cannysrcImage, 100, 200, 3, false);
Canny(srcImage, tempsrcImage, 100, 200, 3, false);
for (int i = 0; i < pyrLevel; i++)
{
pyrDown(tempsrcImage, tempsrcImage);
}
threshold(tempsrcImage, tempsrcImage,30, 255, THRESH_BINARY);
imshow("原始图", tempsrcImage);
waitKey(10);
//模版图片
//Mat modelImage = imread("img/q.png", 0)(Rect(180, 180, 200, 200));
Mat modelImage = imread("img/1.png", 0)(Rect(300, 200, 650, 650));
Mat cannymodelImage,tempmodelImage;
blur(modelImage, modelImage, Size(3, 3));
Canny(modelImage, cannymodelImage, 100, 200, 3, false);
Canny(modelImage, tempmodelImage, 100, 200, 3, false);
for (int i = 0; i < pyrLevel; i++)
{
pyrDown(tempmodelImage, tempmodelImage);
}
threshold(tempmodelImage, tempmodelImage, 30, 255, THRESH_BINARY);
imshow("原始模版", tempmodelImage);
waitKey(10);
//创建模版集
CreateScaledShapeModel(cannymodelImage, pyrLevel, angleStart, angleExtent, angleStep, scaleMin,\
scaleMax, scaleStep, &modelImageSet, &modelPointSet, &scaleSet,&angleSet);
double start = static_cast<double>(getTickCount());
//进行匹配
FindScaledShapeModel(cannysrcImage,modelImageSet, modelPointSet, scaleSet, angleSet, pyrLevel,minScore,&row, \
&col,&scale,&angle,&score);
//标注匹配位置
for (int i = 0; i < row.size(); i++)
{
circle(srcImage, Point(row[i], col[i]), scale[i]*modelImage.rows / 2, 255, 2, 8, 0);
putText(srcImage, format("Number:%d",i),Point(row[i], col[i]), cv::FONT_HERSHEY_TRIPLEX, 0.8, cv::Scalar(255, 200, 200), 2, CV_AA);
cout << "第"<<i<<"号:" <<Point(col[i], row[i]) << " 角度:" << angle[i] << " 缩放:" << scale[i] <<" 成绩:"<<score[i]<< endl;
}
double time = ((double)getTickCount() - start) / getTickFrequency();
cout << "所用时间为:" << time << "秒" << endl;
imshow("原图位置", srcImage);
waitKey(0);
}
void on_mouse(int event, int x, int y, int flags, void* userdata)
{
int font_face = cv::FONT_HERSHEY_COMPLEX;
double font_scale = 2;
int thickness = 2;
if (event == CV_EVENT_MOUSEMOVE)
{
//int value= srcImage.at<uchar>(Point(x, y));
Point pt = Point(x, y);
char temp[16];
//cout << pt.x << " " << pt.y << " 像素值" << value << endl;
}
}
/*************************************************
Function: // CreateScaledShapeModel
Description: // 创建模版集
Input: // Template:模版图片的边缘图
PyrLevel:金字塔缩小层数
AngleStart,AngleExtent,AngleStep:旋转角度候选参数
ScaleMin,ScaleMax,ScaleStep:缩放比例候选参数
Output: // pModelImageSet,pModelPointSet,pScaleSet,pAngleSet:模版集指针
Return: // 无
Others: //
*************************************************/
void CreateScaledShapeModel(Mat Template, int PyrLevel, int AngleStart, int AngleExtent, int AngleStep, float ScaleMin, float ScaleMax, float ScaleStep, \
vector<Mat>* pModelImageSet, vector<int>* pModelPointSet, vector<float>* pScaleSet, vector<float>* pAngleSet)
{
vector<Mat> ModelImageSet;
vector<int> ModelPointSet;
vector<float> AngleSet;
vector<float> ScaleSet;
while (ScaleMin <= ScaleMax)
{
cout << ScaleMax << endl;
ScaleSet.push_back(ScaleMax);
ScaleMax -= ScaleStep;
}
while (AngleStart <= AngleExtent)
{
cout << AngleExtent << endl;
AngleSet.push_back(AngleExtent);
AngleExtent -= AngleStep;
}
//模版生成
for (int level = 0; level <= PyrLevel; level++)
{
Mat pyrmodelImage = Template;
for (int i = 0; i < level; i++)
{
pyrDown(pyrmodelImage, pyrmodelImage);
}
//缩放
for (int i = 0; i < ScaleSet.size(); i++)
{
Mat scaleImage;
resize(pyrmodelImage, scaleImage, Size(round(pyrmodelImage.cols*ScaleSet[i]), round(pyrmodelImage.cols*ScaleSet[i])), 0, 0, INTER_LINEAR);
//旋转
for (int j = 0; j < AngleSet.size(); j++)
{
Mat rotateImage;
imrotate(scaleImage, rotateImage, AngleSet[j]);
//threshold(rotateImage, rotateImage, 1, 255, 0);
Canny(rotateImage, rotateImage, 50, 100, 3, false);
rotateImage /= 255;
//imshow("旋转", rotateImage);
//imwrite("旋转.jpg", rotateImage);
//waitKey(0);
ModelImageSet.push_back(rotateImage);
int pointNum = 0;
for (int i = 0; i < rotateImage.cols; i++)
{
for (int j = 0; j < rotateImage.rows; j++)
{
if (rotateImage.at<uchar>(Point(i, j)) != 0)
pointNum++;
}
}
ModelPointSet.push_back(pointNum);
rotateImage.release();
}
scaleImage.release();
}
}
*pModelImageSet = ModelImageSet;
*pModelPointSet = ModelPointSet;
*pAngleSet = AngleSet;
*pScaleSet = ScaleSet;
}
/*************************************************
Function: // FindScaledShapeModel
Description: // 在一张图片中搜索与模版相似的图形
Input: // Image:待检测图片
ModelImageSet,ModelPointSet,ScaleSet,AngleSet:模版集
PyrLevel:金字塔缩小层数
MinScore:筛选相似度阈值
Output: // pRow,pCol,pScale,pAngle,pScore:输出匹配到的元素参数集合的指针
Return: // 无
Others: // 使用该函数前需要先调用CreateScaledShapeModel
*************************************************/
void FindScaledShapeModel(Mat Image, vector<Mat> ModelImageSet, ve
- 1
- 2
- 3
- 4
- 5
- 6
前往页