opencv实现矩形检测

本文实例为大家分享了opencv实现矩形检测的具体代码,供大家参考,具体内容如下

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <math.h>
#include <string.h>

//////////////////////////////////////////////////////////////////
//函数功能:用向量来做COSα=两向量之积/两向量模的乘积求两条线段夹角
//输入:  线段3个点坐标pt1,pt2,pt0,最后一个参数为公共点
//输出:  线段夹角,单位为角度
//////////////////////////////////////////////////////////////////
double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 )
{
  double dx1 = pt1->x - pt0->x;
  double dy1 = pt1->y - pt0->y;
  double dx2 = pt2->x - pt0->x;
  double dy2 = pt2->y - pt0->y;
  double angle_line = (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);//余弦值
  return acos(angle_line)*180/3.141592653;
}
//////////////////////////////////////////////////////////////////
//函数功能:采用多边形检测,通过约束条件寻找矩形
//输入:  img 原图像
//     storage 存储
//     minarea,maxarea 检测矩形的最小/最大面积
//     minangle,maxangle 检测矩形边夹角范围,单位为角度
//输出:  矩形序列
//////////////////////////////////////////////////////////////////
CvSeq* findSquares4( IplImage* img, CvMemStorage* storage ,int minarea, int maxarea, int minangle, int maxangle)
{
  CvSeq* contours;//边缘
  int N = 6; //阈值分级
  CvSize sz = cvSize( img->width & -2, img->height & -2 );
  IplImage* timg = cvCloneImage( img );//拷贝一次img
  IplImage* gray = cvCreateImage( sz, 8, 1 ); //img灰度图
  IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 ); //金字塔滤波3通道图像中间变量
  IplImage* tgray = cvCreateImage( sz, 8, 1 ); ;
  CvSeq* result;
  double s, t;
  CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );  

  cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height ));
  //金字塔滤波
  cvPyrDown( timg, pyr, 7 );
  cvPyrUp( pyr, timg, 7 );
  //在3个通道中寻找矩形
  for( int c = 0; c < 3; c++ ) //对3个通道分别进行处理
  {
    cvSetImageCOI( timg, c+1 );
    cvCopy( timg, tgray, 0 ); //依次将BGR通道送入tgray
    for( int l = 0; l < N; l++ )
    {
      //不同阈值下二值化
      cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY );

      cvFindContours( gray, storage, &contours, sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
      while( contours )
      { //多边形逼近
       result = cvApproxPoly( contours, sizeof(CvContour), storage,CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );
        //如果是凸四边形并且面积在范围内
       if( result->total == 4 && fabs(cvContourArea(result,CV_WHOLE_SEQ)) > minarea && fabs(cvContourArea(result,CV_WHOLE_SEQ)) < maxarea && cvCheckContourConvexity(result) )
        {
          s = 0;
          //判断每一条边
          for( int i = 0; i < 5; i++ )
          {
            if( i >= 2 )
            {  //角度
              t = fabs(angle( (CvPoint*)cvGetSeqElem( result, i ),(CvPoint*)cvGetSeqElem( result, i-2 ),(CvPoint*)cvGetSeqElem( result, i-1 )));
              s = s > t ? s : t;
            }
          }
          //这里的S为直角判定条件 单位为角度
          if( s > minangle && s < maxangle )
            for( int i = 0; i < 4; i++ )
              cvSeqPush( squares,(CvPoint*)cvGetSeqElem( result, i ));
        }
        contours = contours->h_next;
      }
    }
  }
  cvReleaseImage( &gray );
  cvReleaseImage( &pyr );
  cvReleaseImage( &tgray );
  cvReleaseImage( &timg );
  return squares;
}
//////////////////////////////////////////////////////////////////
//函数功能:画出所有矩形
//输入:  img 原图像
//     squares 矩形序列
//     wndname 窗口名称
//输出:  图像中标记矩形
//////////////////////////////////////////////////////////////////
void drawSquares( IplImage* img, CvSeq* squares ,const char* wndname)
{
  CvSeqReader reader;
  IplImage* cpy = cvCloneImage( img );
  CvPoint pt[4];
  int i;
  cvStartReadSeq( squares, &reader, 0 );
  for( i = 0; i < squares->total; i += 4 )
  {
    CvPoint* rect = pt;
    int count = 4;
    memcpy( pt, reader.ptr, squares->elem_size );
    CV_NEXT_SEQ_ELEM( squares->elem_size, reader );
    memcpy( pt + 1, reader.ptr, squares->elem_size );
    CV_NEXT_SEQ_ELEM( squares->elem_size, reader );
    memcpy( pt + 2, reader.ptr, squares->elem_size );
    CV_NEXT_SEQ_ELEM( squares->elem_size, reader );
    memcpy( pt + 3, reader.ptr, squares->elem_size );
    CV_NEXT_SEQ_ELEM( squares->elem_size, reader );
    //cvPolyLine( cpy, &rect, &count, 1, 1, CV_RGB(0,255,0), 3, CV_AA, 0 );
    cvPolyLine( cpy, &rect, &count, 1, 1, CV_RGB(rand()&255,rand()&255,rand()&255), 1, CV_AA, 0 );//彩色绘制
  }
  cvShowImage( wndname, cpy );
  cvReleaseImage( &cpy );
}

int main()
{
  CvCapture* capture = cvCreateCameraCapture(0);
  IplImage* img0 = 0;
  CvMemStorage* storage = 0;
  int c;
  const char* wndname = "Square Detection Demo"; //窗口名称
  storage = cvCreateMemStorage(0);
  cvNamedWindow( wndname, 1 );
  while (true)
  {
    img0 = cvQueryFrame(capture);
    drawSquares( img0, findSquares4( img0, storage, 100, 2000, 80, 100), wndname );
    cvClearMemStorage( storage ); //清空存储
    c = cvWaitKey(10);
    if( c == 27 )
    break;
  }

  cvReleaseImage( &img0 );
  cvClearMemStorage( storage ); 

  cvDestroyWindow( wndname );
  return 0;
}

效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • OpenCV实现图像轮廓检测以及外接矩形

    前两篇博文分别介绍了图像的边缘检测和轮廓检测,本文接着介绍图像的轮廓检测和轮廓外接矩形: 一.代码部分: // extract_contours.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<cv.h> #include<highgui.h> using namespace cv; using namespace std; int _tmain(int argc, _TCHAR* argv[]) { /

  • 使用OpenCV检测图像中的矩形

    本文实例为大家分享了OpenCV检测图像中矩形的具体代码,供大家参考,具体内容如下 前言 1.OpenCV没有内置的矩形检测的函数,如果想检测矩形,要自己去实现. 2.我这里使用的OpenCV版本是3.30. 矩形检测 1.得到原始图像之后,代码处理的步骤是: (1)滤波增强边缘. (2)分离图像通道,并检测边缘. (3) 提取轮廓. (4)使用图像轮廓点进行多边形拟合. (5)计算轮廓面积并得到矩形4个顶点. (6)求轮廓边缘之间角度的最大余弦. (7)画出矩形. 2.代码 //检测矩形 //

  • opencv实现矩形检测

    本文实例为大家分享了opencv实现矩形检测的具体代码,供大家参考,具体内容如下 #include "cv.h" #include "highgui.h" #include <stdio.h> #include <math.h> #include <string.h> ////////////////////////////////////////////////////////////////// //函数功能:用向量来做COS

  • 基于openCV实现人脸检测

    openCV的人脸识别主要通过Haar分类器实现,当然,这是在已有训练数据的基础上.openCV安装在 opencv/opencv/sources/data/haarcascades_cuda(或haarcascades)中存在预先训练好的物体检测器(xml格式),包括正脸.侧脸.眼睛.微笑.上半身.下半身.全身等. openCV的的Haar分类器是一个监督分类器,首先对图像进行直方图均衡化并归一化到同样大小,然后标记里面是否包含要监测的物体.它首先由Paul Viola和Michael Jon

  • OpenCV实现人脸检测

    前段日子,写了个人脸检测的小程序,可以检测标记图片.视频.摄像头中的人脸.效果还行吧,用的是opencv提供人脸库.至于具体的人脸检测原理,找资料去啃吧. 环境:VS2013+OPENCV2.4.10+Win8.1 一.基于对话框的MFC 首先,新建一个基于对话框的MFC应用程序,命名为myFaceDetect(取消"安全开发周期(SDL)检查"勾选,我自己习惯取消这个). 放置Button,设置Button的ID和Caption. 图片按钮--ID:IDC_FACEDETECT 视频

  • Python OpenCV调用摄像头检测人脸并截图

    本文实例为大家分享了Python OpenCV调用摄像头检测人脸并截图的具体代码,供大家参考,具体内容如下 注意:需要在python中安装OpenCV库,同时需要下载OpenCV人脸识别模型haarcascade_frontalface_alt.xml,模型可在OpenCV-PCA-KNN-SVM_face_recognition中下载. 使用OpenCV调用摄像头检测人脸并连续截图100张 #-*- coding: utf-8 -*- # import 进openCV的库 import cv2

  • Python基于OpenCV实现人脸检测并保存

    本文实例为大家分享了Python基于OpenCV实现人脸检测,并保存的具体代码,供大家参考,具体内容如下 安装opencv 如果安装了pip的话,Opencv的在windows的安装可以直接通过cmd命令pip install opencv-python(只需要主要模块),也可以输入命令pip install opencv-contrib-python(如果需要main模块和contrib模块) 详情可以点击此处 导入opencv import cv2 所有包都包含haarcascade文件.这

  • android端使用openCV实现车牌检测

    现在,汽车的踪影无处不在,公路上疾驰,大街边临停,小区中停靠,车库里停泊.管理监控如此庞大数量的汽车是个头疼的问题.精明的人们把目光放在车牌上,因为车牌是汽车的"身份证".所以车牌识别成为了焦点,而车牌检测是车牌识别的基础和前提.本篇文章,主要讨论使用openCV实现车牌检测. openCV是开源计算机视觉库,基于计算机视觉与机器学习,提供强大的图像处理能力.我们可以快速集成openCV库到android端,其中一种方式是直接安装openCV Manager,按需使用:启动服务去动态加

  • Android 利用OpenCV制作人脸检测APP

    目录 前言 第一步:下载并安装Android studio 第二步:下载SDK tools 第三步:新建一个Android APP项目 第四步:下载Opencv 第五步:导入OpenCV 第六步:添加代码 第七步:连接手机运行程序 前言 本篇文章手把手教大家使用OpenCV来实现一个能在安卓手机上运行的人脸检测APP.其实不仅仅是能检测人脸,还能检测鼻子,嘴巴,眼睛和耳朵.花了不少精力写这篇文章,希望点赞收藏关注. 无图无真相,先把APP运行的结果给大家看看. 如上图所示,APP运行后,点击"选

  • 基于opencv的行人检测(支持图片视频)

    基于方向梯度直方图(HOG)/线性支持向量机(SVM)算法的行人检测方法中存在检测速度慢的问题,如下图所示,对一张400*490像素的图片进行检测要接近800毫秒,所以hog+svm的方法放在视频中进行行人检测时,每秒只能检测1帧图片,1帧/s根本不能达到视频播放的流畅性. 本文采用先从视频每帧的图像中提取出物体的轮廓(也可以对前后两针图片做差,只对有变化的部分进行检测,其目的一样,都是减少运算的面积),再对每个轮廓进行HOG+SVM检测,判断是否为行人.可以大大的缩减HOG+SVM的面积,经实

  • 基于深度学习和OpenCV实现目标检测

    目录 使用深度学习和 OpenCV 进行目标检测 MobileNets:高效(深度)神经网络 使用 OpenCV 进行基于深度学习的对象检测 使用 OpenCV 检测视频 使用深度学习和 OpenCV 进行目标检测 基于深度学习的对象检测时,您可能会遇到三种主要的对象检测方法: Faster R-CNNs (Ren et al., 2015) You Only Look Once (YOLO) (Redmon et al., 2015) Single Shot Detectors (SSD)(L

  • Python OpenCV实现图形检测示例详解

    目录 1. 轮廓识别与描绘 1.1 cv2.findComtours()方法 1.2 cv2.drawContours() 方法 1.3 代码示例 2. 轮廓拟合 2.1 矩形包围框拟合 - cv2.boundingRect() 2.2圆形包围框拟合 - cv2.minEnclosingCircle() 3. 凸包 绘制 4. Canny边缘检测 - cv2.Canny() 4.1 cv2.Canny() 用法简介 4.2 代码示例 5. 霍夫变换 5.1 概述 5.2 cv2.HoughLin

随机推荐