这段代码实现了从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;
//}
//
//