这段代码实现了从usb摄像头读取视频,并且分割后只显示自己想要部分(分割就是普通矩形分割,参数可以随意修改),再进行灰度化、二值化、滤波之后再进行霍夫变换识别圆形,并用彩色标出来,同时窗口显示识别到圆的个数,以及半径,圆心坐标点。图像保存这段代码是注释掉的,需要自己在指定路径建个文件夹,间隔多久保存可以改变if(i>2)那句的2值来设定。这个原本主要就是用来识别象棋的一部分。
/****************************************************************************************************
2018_4_17.cpp: 定义控制台应用程序的入口点。
4月18日:预处理(灰度化、二值化、滤波)已完成
保存图片已完成
进行霍夫圆变换和角点检测、直线检测时用高斯滤波效果似乎会好一些,但是处理识别汉字时,用普通blue
即可,因为高斯滤波虽然把噪声滤除了,但是图片明显模糊了很多
4月19日:将霍夫变换弄好了,可以检测到32个圆,但是相机标定没有弄好。
实现了间隔一定时间动态显示,但是总是会多识别出一两个圆。
因此着手写误判程序
思路:1,改变二值化阈值参数。
2,圆心距离要大于半径(20)
****************************************************************************************************/
#include "stdafx.h"
#include "core/core.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <set>
#include<stdio.h>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>//for camera
#include <opencv2/video.hpp>
#include <opencv2/imgPRoc//imgproc.hpp>
#include <opencv2/ml/ml.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/ml/ml.hpp"
#include <time.h>
#include <ctime>
#include <iostream>
#include <string>
using namespace std;
using namespace cv;
int main(int argc, char ** argv)
{
int i=1000;
int n = 1;
Mat frame,edges;
//【1】从摄像头读入视频
VideoCapture capture(1); //该参数为0,则打开计算机自带摄像头,如果为1则打开外置USB摄像头
//namedWindow("frame", CV_WINDOW_NORMAL);
// namedWindow("预处理后的视频", 0);//参数为零,则可以自由拖动
// namedWindow("原始视频", 0);//参数为零,则可以自由拖动
//setWindowProperty("frame", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);//设置窗口全屏
capture.set(CAP_PROP_FRAME_WIDTH, 1920.0);//设置摄像头采集图像分辨率
capture.set(CAP_PROP_FRAME_HEIGHT, 1080.0);
while (1)
{
i++;
capture >> frame;// //读取当前帧,capture >> frame与capture.read(frame)功能一样,
if (frame.empty())
{
return 0;
}
//隔一段时间保存一张图片
if (i>=2)//通过改变i后面的值来刷新图片界面
{
i = 0;
namedWindow("【原始图】", 0);//参数为零,则可以自由拖动
imshow("【原始图】", frame);
Rect rect(600, 0, 1205, 1035); //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut = Mat(frame, rect); //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy = image_cut.clone(); //clone函数创建新的图片
namedWindow("分割后的图片", 0);//参数为零,则可以自由拖动
imshow("分割后的图片", image_copy);
//灰度化
cvtColor(image_copy, edges, CV_BGR2GRAY);//灰度化
//二值化
threshold(edges, edges, 105, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
//使用3*3内核来降噪
blur(edges, edges, Size(3, 3));//进行模糊
//保存图片
// char* fileName = new char[120];
// sprintf(fileName, "%s%d%s", "E:\\OCR_Recognition\\shipin_capture\\shipin_capture", n++, ".jpg");
// imwrite(fileName, edges);
/*************************************************************************************************************/
//角点检测
/*************************************************************************************************************/
// Mat srcimage;
Mat grayimage;
// vector<Point2f> corners; //角点坐标
// Size PatSize;
// PatSize.width = 8;
// PatSize.height = 7;
// srcimage = edges.clone(); //clone函数创建新的图片
// bool ret = findChessboardCorners(srcimage, PatSize, corners);
// //Mat viewGray;
// //cvtColor(srcimage, viewGray, COLOR_BGR2GRAY);
// //cornerSubPix(viewGray, corners, Size(11, 11),
// // Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));
// drawChessboardCorners(image_copy, PatSize, Mat(corners), ret);
// namedWindow("角点检测后", 0);
// imshow("角点检测后", image_copy);
---------------------------【1】定义一些局部变量-----------------------------
//Mat dstImage;//目标图
//Mat normImage;//归一化后的图
//Mat scaledImage;//线性变换后的八位无符号整型的图
//
---------------------------【2】初始化---------------------------------------
置零当前需要显示的两幅图,即清除上一次调用此函数时他们的值
//dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
//g_srcImage1 = g_srcImage.clone();
//
---------------------------【3】正式检测-------------------------------------
进行角点检测
//cornerHarris(g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT);
//
归一化与转换
//normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
//convertScaleAbs(normImage, scaledImage);//将归一化后的图线性变换成8位无符号整型
//
// //---------------------------【4】进行绘制-------------------------------------
// // 将检测到的,且符合阈值条件的角点绘制出来
//for (int j = 0; j < normImage.rows; j++)
//{
// for (int i = 0; i < normImage.cols; i++)
// {
// if ((int)normImage.at<float>(j, i) > thresh + 80)
// {
// circle(g_srcImage1, Point(i, j), 5, Scalar(10, 10, 255), 2, 8, 0);
// circle(scaledImage, Point(i, j), 5, Scalar(0, 10, 255), 2, 8, 0);
// }
// }
//}
//---------------------------【4】显示最终效果---------------------------------
//imshow(WINDOW_NAME1, g_srcImage1);
//imshow(WINDOW_NAME2, scaledImage);
/*************************************************************************************************************/
//进行霍夫圆变换
/*************************************************************************************************************/
//【4】进行霍夫圆变换
// 第五个参数 圆的圆心之间的最小距离
vector<Vec3f> circles;
HoughCircles(edges, circles, CV_HOUGH_GRADIENT, 1.5, 38, 100, 25, 37, 43);
//【5】依次在图中绘制出圆
for (size_t i = 0; i < circles.size(); i++)
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
cout << "圆心 " << i << "= " << center << ";\n" << endl;
cout << "半径= " << i << "= " << radius << ";\n" << endl;
//绘制圆心
circle(image_copy, center, 3, Scalar(0, 255, 0), -1, 8, 0);
//绘制圆轮廓
circle(image_copy, center, radius, Scalar(155, 50, 255), 3, 8, 0);
//绘制圆心
circle(edges, center, 3, Scalar(0, 255, 0), -1, 8, 0);
//绘制圆轮廓
circle(edges, center, radius, Scalar(155, 50, 255), 3, 8, 0);
}
cout << "共检测到圆" << circles.size() << " 个圆" << ";\n" << endl;
//【6】显示效果图
namedWindow("【二值化后效果图】", 0);//参数为零,则可以自由拖动
imshow("【二值化后效果图】", edges);
namedWindow("【彩色效果图】", 0);//参数为零,则可以自由拖动
imshow("【彩色效果图】", image_copy);
/*************************************************************************************************************/
//角点检测
/*************************************************************************************************************/
//Mat srcimage;
//Mat grayimage;
//vector<Point2f> corners;
//Size PatSize;
//PatSize.width = 8;
//PatSize.height = 7;
//srcimage = imread("a111.bmp");
//bool ret = findChessboardCorners(srcimage, PatSize, corners);
Mat viewGray;
cvtColor(srcimage, viewGray, COLOR_BGR2GRAY);
cornerSubPix(viewGray, corners, Size(11, 11),
Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));
//drawChessboardCorners(srcimage, PatSize, Mat(corners), ret);
//namedWindow("chessboard corners");
//imshow("chessboard corners", srcimage);
}
//进行canny边缘检测并显示
// Canny(edges, edges, 0, 30, 3);
//**************************************************************************************************
// //直方图均衡
// adaptiveHistEqual(spineGray, spineAhe, 0.01);//直方图均衡
//
// namedWindow("直方图均衡后ahe", 0);
// imshow("直方图均衡后ahe", spineAhe);
// // waitKey();
// imwrite("直方图均衡后gray2.jpg", spineAhe);
// // WriteData("/Users/eternity/Desktop/未命名文件夹/gray2.txt", spineAhe);
//**************************************************************************************************
// imshow("原始视频", frame);
// imshow("预处理后的视频", edges); //显示当前帧
if (waitKey(30) == 27)
{
break;
}
}
return 0;
}
//-----------------------------------【on_HoughLines( )函数】--------------------------------
// 描述:回调函数
//----------------------------------------------------------------------------------------------
//
//void on_CornerHarris(int, void*)
//{
// //---------------------------【1】定义一些局部变量-----------------------------
// Mat dstImage;//目标图
// Mat normImage;//归一化后的图
// Mat scaledImage;//线性变换后的八位无符号整型的图
//
// //---------------------------【2】初始化---------------------------------------
// //置零当前需要显示的两幅图,即清除上一次调用此函数时他们的值
// dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
// g_srcImage1 = g_srcImage.clone();
//
// //---------------------------【3】正式检测-------------------------------------
// //进行角点检测
// cornerHarris(g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT);
//
// // 归一化与转换
// normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
// convertScaleAbs(normImage, scaledImage);//将归一化后的图线性变换成8位无符号整型
//
// //---------------------------【4】进行绘制-------------------------------------
// // 将检测到的,且符合阈值条件的角点绘制出来
// for (int j = 0; j < normImage.rows; j++)
// {
// for (int i = 0; i < normImage.cols; i++)
// {
// if ((int)normImage.at<float>(j, i) > thresh + 80)
// {
// circle(g_srcImage1, Point(i, j), 5, Scalar(10, 10, 255), 2, 8, 0);
// circle(scaledImage, Point(i, j), 5, Scalar(0, 10, 255), 2, 8, 0);
// }
// }
// }
// //---------------------------【4】显示最终效果---------------------------------
// //imshow(WINDOW_NAME1, g_srcImage1);
// //imshow(WINDOW_NAME2, scaledImage);
//
//}
//#include "stdafx.h"
//#include "core/core.hpp"
//#include <opencv2/imgproc/imgproc.hpp>
//#include <opencv2/highgui/highgui.hpp>
//#include <iostream>
//#include <set>
//#include<stdio.h>
//
//#include <opencv2/core.hpp>
//#include <opencv2/opencv.hpp>
//#include <opencv2/highgui.hpp>
//#include <opencv2/videoio.hpp>//for camera
//#include <opencv2/video.hpp>
//#include <opencv2/ml/ml.hpp>
//#include "opencv2/ml/ml.hpp"
//#include <time.h>
//#include <ctime>
//#include <string>
//using namespace std;
//using namespace cv;
-----------------------------------【命名空间声明部分】---------------------------------------
描述:包含程序所使用的命名空间
-----------------------------------------------------------------------------------------------
//
-----------------------------------【main( )函数】--------------------------------------------
描述:控制台应用程序的入口函数,我们的程序从这里开始
-----------------------------------------------------------------------------------------------
//int main()
//{
//
//
//
// //【1】载入原始图和Mat变量定义
// Mat srcImage = imread("3.jpg"); //工程目录下应该有一张名为1.jpg的素材图
// Mat midImage, dstImage;//临时变量和目标图的定义
//
// //【2】显示原始图
// namedWindow("【原始图】", 0);//参数为零,则可以自由拖动
// imshow("【原始图】", srcImage);
//
// Rect rect(600, 0, 1205, 1035); //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
// Mat image_cut = Mat(srcImage, rect); //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
// Mat image_copy = image_cut.clone(); //clone函数创建新的图片
//
// namedWindow("分割后的图片", 0);//参数为零,则可以自由拖动
// imshow("分割后的图片", image_copy);
//
//
// //【3】转为灰度图,进行图像平滑
// cvtColor(image_copy, midImage, CV_BGR2GRAY);//灰度化
//
// //二值化
// threshold(midImage, midImage, 128, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
//
// //使用3*3内核来降噪
// blur(midImage, midImage, Size(3, 3));//进行模糊
// //GaussianBlur(midImage, midImage, Size(9, 9), 2, 2);
//
//
// //Rect rect(600,0, 1205, 1035); //创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
// //Mat image_cut = Mat(midImage, rect); //从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
// //Mat image_copy = image_cut.clone(); //clone函数创建新的图片
//
// //namedWindow("分割后的图片", 0);//参数为零,则可以自由拖动
// //imshow("分割后的图片", image_copy);
//
//
//
//
//
//
//
// //【4】进行霍夫圆变换
// vector<Vec3f> circles;
HoughCircles(midImage, circles, CV_HOUGH_GRADIENT, 1.5, 10, 200, 100, 0, 0);
//
// // 第五个参数 圆的圆心之间的最小距离
// HoughCircles(midImage, circles, CV_HOUGH_GRADIENT, 1.5, 35, 100, 25, 36, 43);
//
// //【5】依次在图中绘制出圆
// for (size_t i = 0; i < circles.size(); i++)
// {
// Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
// int radius = cvRound(circles[i][2]);
// cout << "圆心 " << i << "= " << center << ";\n" << endl;
// cout << "半径= " << i << "= " << radius << ";\n" << endl;
//
// //绘制圆心
// circle(midImage, center, 3, Scalar(0, 255, 0), -1, 8, 0);
// //绘制圆轮廓
// circle(midImage, center, radius, Scalar(155, 50, 255), 3, 8, 0);
// //绘制圆心
// circle(image_copy, center, 3, Scalar(0, 255, 0), -1, 8, 0);
// //绘制圆轮廓
// circle(image_copy, center, radius, Scalar(155, 50, 255), 3, 8, 0);
// }
// cout << "共检测到圆" << circles.size() << " 个圆" << ";\n" << endl;
//
// //【6】显示效果图
// namedWindow("【二值化后效果图】", 0);//参数为零,则可以自由拖动
// imshow("【二值化后效果图】", midImage);
//
// namedWindow("【彩色效果图】", 0);//参数为零,则可以自由拖动
// imshow("【彩色效果图】", image_copy);
// waitKey(0);
//
// return 0;
//}
//
//
//
//
//
//int main(int argc, char ** argv)
//{
// char filename[1024];
//
// if (argc == 1)
// sprintf(filename, "%s", "camera.avi");
// if (argc == 2)
// sprintf(filename, "%s", "123");
//
//
// VideoCapture capture;
// capture.open(0);
// if (!capture.isOpened())
// {
// cout << "Could not initialize capturing...\n" << endl;
// return -1;
// }
//
// //按时间格式命名
// time_t now = time(NULL);获取1970.1.1至当前秒数time_t
// struct tm * timeinfo = localtime(&now); //创建TimeDate,并转化为当地时间,
// //struct tm * timeinfo = gmtime ( &currTime ); //创建TimeDate,并转化为GM时间,
// char path[60];
// strftime(path, 60, "%Y_%m_%d_%H_%M_%S", timeinfo);
// char strPath[100];
// sprintf(strPath, "%s.avi", path);//将创建文件的命令存入cmdchar中
//
// //保存为avi格式视频
// Mat frame;
// VideoWriter writer;
// writer.open(strPath, CV_FOURCC('X', 'V', 'I', 'D'), 25, Size(1920, 1080), true);//Size(640, 480)//Size(frame.rows, frame.cols)//"cam.avi"
//
// int n = 1;
// while (true)
// {
// capture >> frame;
// char* cstr = new char[120];
//
// // sprintf(cstr, "%s%d%s", "E:\\OpenCVWorkSpace\\saveCamAsVideo\\saveCamAsVideo\\savedPic\\Pic", n++, ".jpg");
//
// sprintf(cstr, "%s%d%s", "E:\\OCR_Recognition\\shipin_capture\\shipin_capture", n++, ".jpg");
//
//
//
//
// imwrite(cstr, frame);
//
// imshow("Video_Capture", frame);
// if (frame.empty())
// {
// break;
// }
// writer << frame;
// waitKey(3);
//
// }
//
// //return 0;
//}
//
//