2019-01-18 12:01:09 qq_34814092 阅读数 321

Java OpenCV-4.0.0 图像处理16 霍夫变换-圆形检测

Java OpenCV-4.0.0 霍夫变换-圆形检测

因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波。
基于效率考虑,Opencv中实现的霍夫变换圆检测是基于图像梯度的实现,分为两步:
1.检测边缘,发现可能的圆心。
2.基于第一步的基础上从候选圆心开始计算最佳半径大小。2. 基于第一步的基础上从候选圆心开始计算最佳半径大小。
3.如果要检测出所有的圆形结构请使用Java OpenCV-4.0.0 图像处理25 图像矩(Image Moments)

package com.xu.image;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

/**  
 * 
 * @Title: ImageThreshold.java   
 * @Description: OpenCV-4.0.0 测试文件
 * @Package com.xu.test   
 * @author: xuhyacinth     
 * @date: 2019年7月10日12:13:13   
 * @version: V-1.0.0 
 * @Copyright: 2019 xuhyacinth
 *
 */
public class ImageThreshold {

	static {
		//在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}

	public static void main(String[] args) {
		houghCircles();
	}
	
	/**
	 * OpenCV-4.0.0 霍夫变换-圆形检测
	 * @return: void
	 * @date: 2019年7月10日 上午12:26:07
	 */
	public static void houghCircles() {
		Mat src=Imgcodecs.imread("C:\\Users\\Administrator\\Pictures\\0001.jpg");
		Mat gary=new Mat();
		Mat dst=new Mat();
		Mat lines=new Mat();
		//1.中值模糊(滤波-->平滑)
		Imgproc.medianBlur(src, dst, 1);
		//2.灰度图片
		Imgproc.cvtColor(dst, gary, Imgproc.COLOR_RGB2GRAY);
		//3.霍夫变换-圆形检测
		//Imgproc.HoughCircles(8位灰度图片,写入特征图片,检测方法,深度,区域,参数1,参数2,最小半径,最大半径)
		Imgproc.HoughCircles(gary, lines,Imgproc.HOUGH_GRADIENT, 1 , 20, 100 ,30, 10, 500);
		double[] date;
		for(int i=0,len=lines.rows();i<len;i++) {
			date=lines.get(i, 0).clone();
			Imgproc.circle(src, new Point((int)date[0],(int)date[1]), (int)date[2], new Scalar(0, 0, 255),2,Imgproc.LINE_AA);//园周
			Imgproc.circle(src, new Point((int)date[0],(int)date[1]), 2, new Scalar(0, 0, 255),2,Imgproc.LINE_AA);//圆形
		}
		Imgproc.resize(src, src, new Size(src.cols()/2,src.rows()/2));
		HighGui.imshow("霍夫变换-圆形检测", src);
		HighGui.waitKey(0);
	}
	
}

霍夫-圆形检测

2018-07-10 18:01:12 qq_32864683 阅读数 521

        霍夫变换是在图像处理中进行直线、圆形检测和拟合一种非常重要的手段。无论是对直线还是圆形进行检测和拟合,霍夫变换的中心思想就是将图像像素坐标转换到参数坐标。

关于直线的霍夫变换原理,下面一张图描述得非常清楚:

        通过将像素坐标空间转换到参数空间,在像素坐标空间中的每一个点在坐标空间中都会变成一条直线,而所有这些直线都会倾向于相交于同一个点,这一点的坐标所代表的参数就是拟合出的直线的参数。霍夫变换检测圆形的原理和直线的也相似,不同之处就在于,在像素坐标空间中,表示一条直线的方程需要两个参数,而表示一个圆的方程需要三个参数(圆心的横坐标、圆心的纵坐标、半径),但是往往增加一个参数所带来的计算开销增加q非常巨大的,这也是为什么霍夫变换检测圆形在对实时性要求别叫高的工程项目中使用的非常少。

鉴于Opencv中有关于霍夫变化可以直接调用的接口,该文下面就主要介绍这些接口函数的调用方法和参数的意义,常用的接口函数包括:HoughLines()、HoughLinesP()、HoughCircles()

  • HoughLines()
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )

参数说明:

  1. image: 8位单通道二进制图像,可以载入任意图像由函数修改成此格式
  2. lines: 输出直线矢量,每一条线有两个元素的矢量(ρ , θ)表示,ρ是离坐标原点(0, 0)也就是图像左上角的距离,θ是弧度线条旋转角度(0度表示垂直线,π/2度表示水平线)。
  3. rho: 以像素为单位的距离精度,其它表述还有是直线搜索时的进步尺寸的单位半径
  4. theta: 以弧度为单位的角度精度。其它表述还有是直线搜索时的进步尺寸的单位角度。
  5. threshold: 累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的直线才可以被检测通过并返回到结果中。
  6. srn: 对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho, 而精确的累加器进步尺寸为rho/srn。有默认值0
  7. stn:对于多尺度霍夫变换,stn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0, 就表示使用经典的霍夫变换,扶着这两个参数都应该为正数。经典霍夫变换和多尺度霍夫变换就是在这进行区分的。有默认值0

代码演示:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main(){
    Mat image;
    image=imread("5.jpg");
    Mat image_copy;
    image_copy=image.clone();
    imshow("1",image);
    cvtColor(image,image,CV_RGB2GRAY);//灰度化
    GaussianBlur(image,image,Size(9,9),2,2);//高斯模糊
    Canny(image,image,30,60);//Canny边缘检测
    vector<Vec2f> lines;
    HoughLines(image, lines, 1, CV_PI/180,230, 0, 0);//霍夫变换
    for(size_t i = 0; i < lines.size(); i++)//显示检测到的直线
    {
        float rho = lines[i][0];
        float theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a * rho, y0 = b * rho;
        pt1.x = cvRound(x0 + 1000*(-b));
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));
        line(image_copy, pt1, pt2, Scalar(0, 0, 255), 2);
    }
    imshow("2",image_copy);
    waitKey(0);
    return 0;
}

        在进行直线检测之前,我们先将RGB图转换成为灰度图像,然后进行高斯模糊,通过Canny边缘检测算法得到图像的二值边缘图像,将二值边缘图像作为HoughLines()函数的图像输入,输入的vector容器中包含的就是检测到的直线的信息。效果如下图所示:


  • HoughLinesP()
        我们可以发现HoughLinesP函数比HoughLines()函数多了一个P,区别就在于:在opencv中可以用HoughLines()函数来调用标准霍夫变换(SHT)和多尺度霍夫变换(MSHT),而HoughLinesP()函数用于调用累计概率霍夫变换PPHT,累计概率霍夫变换执行效率会比前者更高。
void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )  

参数说明:

  1. image: 8位单通道二进制图像,可以载入任意图像由函数修改成此格式
  2. lines: 线段输出矢量,每一条之先都由四个矢量元素(x1, y1, x2, y2)表示,其中(x1, y1)和(x2, y2)分别是检测到直线线段的两个端点。
  3. rho: 以像素为单位的直线搜寻步长
  4. theta: 以弧度为单位的直线搜寻步长
  5. threshold: 累加器阈值参数,只有大于threshold的直线结果才能被检测通过并返回到结果中
  6. minLineLength: 线段长度最小值,如果线段长度小于这个值则线段结果不显示,有默认值0
  7. maxLineGap: 允许点连接到相同直线的中间距离的最大值,如果超过这个最大值则点不会被划分到该直线。有默认值0

代码演示:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main(){
    Mat image;
    image=imread("5.jpg");
    Mat image_copy;
    image_copy=image.clone();
    imshow("1",image);
    cvtColor(image,image,CV_RGB2GRAY);
    blur(image,image,Size(5,5));
    Canny(image,image,30,60);
    vector<Vec4i> Lines;
    HoughLinesP(image, Lines, 1, CV_PI / 180,40,40,5);//霍夫直线检测
    //在图中绘出线段
    for(int i=0;i<Lines.size();i++)
        line(image_copy,Point(Lines[i][0],Lines[i][1]),Point(Lines[i][2],Lines[i][3]),Scalar(0,255,0),2);
    imshow("2",image_copy);
    waitKey(0);
    return 0;
}

        HoughLinesP()函数保存直线信息的方式和HoughLines()函数的方式也不一样,HoughLines()函数保存的信息是截距和斜率,而HoughLinesP()函数保存的是在直线上的两点(两点确定一条直线)。示例代码中设置的参数限制了线段的最小长度和艰巨最大值,可见效果如下:


  • HoughCircles()
        霍夫圆变换的基本原理和霍夫线变换类似,值时点对应的二维极径极角空间被三维的圆心点x, y还有半径r空间取代。对直线来说,一条直线能由参数极径极角(r, θ),而对圆来说,我们需要三个参数来表示一个圆,现在原图像的边缘图像的任意点对应的经过这个点的所有可能圆是在三维空间由下面这三个参数来表示了,对应一条三维空间的曲线。 
void cv::HoughCircles   (   InputArray      image,
        OutputArray     circles,
        int     method,
        double      dp,
        double      minDist,
        double      param1 = 100,
        double      param2 = 100,
        int     minRadius = 0,
        int     maxRadius = 0 
    )   

参数说明:

  1. image: 输入图像为8位单通道灰度图
  2. circles: 检测到圆的输出矢量,每个矢量都是三个浮点元素构成(x,y,radius)
  3. method: 检测方法,可以查看HoughModes查看具体细节,但目前只有HOUGH_GRADIENT(霍夫梯度)一种方法可以使用。
  4. dp: 用来检测圆心的累加器图像的分辨率与输入图像之比的倒数,且此参数允许创建一个比输入图像分辨率低的累加器。例如,如果dp=1,累加器和输入图像具有相同的分辨率,如果dp=2累加器便有输入图像一半那么大的宽度和高度。
  5. minDist: 霍夫检测到的圆的圆心之间的最小距离,即让算法能明显区分的两个不同圆之间的最小距离。这个参数如果太小的话,多个相邻的圆可能被错误的检测成了一个重合的圆。繁殖这个参数设置太大,某些圆就不能被检测出来了。也就是超过这个距离就是两个圆,否则是一个圆。
  6. param1: 指定检测方法的第一个参数,当前可用方法是HOUGH_GRADIENT,它表示传递给Canny边缘检测算子的高阈值(低阈值是高阈值的一半),有默认值100
  7. param2: 指定检测方法的第二个参数,对于HOUGH_GRADIENT方法,它表示在检测阶段圆心的累加器阈值。它越小就越可以检测到更多根本不存在的圆,而它越大的话能通过检测的圆就更加接近完美的圆形了。有默认值100
  8. minRadius: 圆的最小半径
  9. maxRadius: 圆的最大半径

代码演示:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main(){
    Mat image;
    image=imread("4.jpg");
    Mat image_copy;
    image_copy=image.clone();
    imshow("1",image);
    cvtColor(image,image,CV_RGB2GRAY);
    blur(image,image,Size(5,5));
    Canny(image,image,30,60);
    vector<Vec3f> circles;
    HoughCircles(image, circles, CV_HOUGH_GRADIENT, 1, image.rows/8, 100, 100, 0, 0);

    //绘制检测到的圆
    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]);
        circle(image_copy, center, 3, Scalar(0, 255, 0), -1, 8, 0);
        circle(image_copy, center, radius, Scalar(0, 255, 0), 3, 8, 0);
    }

    imshow("2",image_copy);
    waitKey(0);
    return 0;
}

效果图:


原图

霍夫圆变换检测

总结:

        霍夫变换是在二值边缘图像的基础上进行计算的,这也就涉及到一个问题:二值边缘图像的像素数量将会直接影响霍夫变换的速度,也就是说二值边缘图像中的边缘像素点越少,则霍夫变换的计算开销越小,像素点越多则计算开销越大,而且这种开销的增加不是呈线性的。因此,在对实时性要求较高的工程中,如果使用到了霍夫变换,那么就要严格控制输入的二值边缘图像的边缘像素的数量,该文中的边缘检测使用的都是Canny算法,Canny的参数以及Hough变换函数的参数需要在效果和速度两者权衡的情况下设置得当。

2019-02-02 15:26:53 qq_40311281 阅读数 2109

实现所给硬币图像中的硬币检测及计数

要求完成功能:自行查找、阅读有关的采用Hough变换来检测图像中圆的资料,设计实现所给图像中圆形的检测,要求检测出图像中硬币个数以及各个硬币的直径。

本题难度系数:★★★★

GUI界面设计参考:MATLAB学习笔记(十一)——MATLAB图形用户界面设计

https://www.cnblogs.com/BlueMountain-HaggenDazs/p/4307777.html

我采用了霍夫变换对所给图形进行了检测和统计个数:

原图如下:

检测后的效果:

全部matlab代码如下:

Hough.m文件:

function varargout = Hough(varargin)
% HOUGH MATLAB code for Hough.fig
%      HOUGH, by itself, creates a new HOUGH or raises the existing
%      singleton*.
%
%      H = HOUGH returns the handle to a new HOUGH or the handle to
%      the existing singleton*.
%
%      HOUGH('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in HOUGH.M with the given input arguments.
%
%      HOUGH('Property','Value',...) creates a new HOUGH or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before Hough_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to Hough_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help Hough
% Last Modified by GUIDE v2.5 10-Jan-2019 20:43:12
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @Hough_OpeningFcn, ...
                   'gui_OutputFcn',  @Hough_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before Hough is made visible.
function Hough_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to Hough (see VARARGIN)

% Choose default command line output for Hough
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes Hough wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = Hough_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%打开文件
global img
[filename, pathname]= ...
    uigetfile({'*.*';'*.bmp';'*.tif';'*.png';'*.jpg'},'select picture');
str= [pathname filename];
img= imread(str);
axes(handles.axes1);
imshow(img);

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global img;
global Gray;
 img=imresize(img,0.5);
[m,n,l] = size(img);
if l == 3
    Gray = rgb2gray(img);    %如果为彩色图 则转化为灰度图
else
    Gray=img;
end
axes(handles.axes1);
imshow(Gray);

% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on button press in pushbutton5.
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global Gray;
global BW1;
BW1=im2bw(Gray,graythresh(Gray));   %转化为二值图像
axes(handles.axes2);
imshow(BW1)


% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global BW1;
BW1=imopen(BW1,strel('disk',3));  %转化为二值图像
axes(handles.axes2);
imshow(BW1)


% --- Executes on button press in pushbutton7.
function pushbutton7_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton7 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global BW1;
BW1=imfill(~BW1,'holes');  %填充图像空洞   
axes(handles.axes2);
imshow(BW1)


% --- Executes on button press in pushbutton8.
function pushbutton8_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%sobel算子边缘检测
global BW1;
BW1 = edge(BW1,'sobel');  
axes(handles.axes2);
imshow(BW1)


% --- Executes on button press in pushbutton9.
function pushbutton9_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton9 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global BW1;
global para;
%hough检测
step_r = str2num(get(handles.edit1, 'String'));
step_angle = str2num(get(handles.edit2, 'String'));
minr =str2num(get(handles.edit3, 'String'));
maxr = str2num(get(handles.edit4, 'String')); 
thresh = str2num(get(handles.edit5, 'String'));

[Hough_Space,Hough_Circle,para] = hough_circle(BW1,step_r,step_angle,minr,maxr,thresh);  
axes(handles.axes2);
imshow(Hough_Circle);


% --- Executes on button press in pushbutton10.
function pushbutton10_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton10 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global para;
global circleParaXYR;
circleParaXYR=para;  
%通过位置求圆心和半径
[r,c]=size(circleParaXYR);
for i=1:r
    a='handles.edit';
    b=5+i;
    c=[a num2str(b)];
    d=[a num2str(5+r+1)];
  set(eval(c),'string',['(' num2str(floor(circleParaXYR(i,1))) ',' num2str(floor(circleParaXYR(i,2))) ')', num2str(2*floor(circleParaXYR(i,3)))]);
  set(eval(d),'string',num2str(r));
end
 

% --- Executes on button press in pushbutton11.
function pushbutton11_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton11 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%标出圆  
global img;
global circleParaXYR;
axes(handles.axes2);
imshow(img);
hold on;  
 plot(circleParaXYR(:,2), circleParaXYR(:,1), 'r+');  
 for k = 1 : size(circleParaXYR, 1)  
  t=0:0.01*pi:2*pi;  
  x=cos(t).*circleParaXYR(k,3)+circleParaXYR(k,2);y=sin(t).*circleParaXYR(k,3)+circleParaXYR(k,1);  
  plot(x,y,'r-');  
 end  



function edit1_Callback(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit1 as text
%        str2double(get(hObject,'String')) returns contents of edit1 as a double


% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit2_Callback(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit2 as text
%        str2double(get(hObject,'String')) returns contents of edit2 as a double


% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit3_Callback(hObject, eventdata, handles)
% hObject    handle to edit3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit3 as text
%        str2double(get(hObject,'String')) returns contents of edit3 as a double


% --- Executes during object creation, after setting all properties.
function edit3_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit4_Callback(hObject, eventdata, handles)
% hObject    handle to edit4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit4 as text
%        str2double(get(hObject,'String')) returns contents of edit4 as a double


% --- Executes during object creation, after setting all properties.
function edit4_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit5_Callback(hObject, eventdata, handles)
% hObject    handle to edit5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit5 as text
%        str2double(get(hObject,'String')) returns contents of edit5 as a double


% --- Executes during object creation, after setting all properties.
function edit5_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit6_Callback(hObject, eventdata, handles)
% hObject    handle to edit6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit6 as text
%        str2double(get(hObject,'String')) returns contents of edit6 as a double


% --- Executes during object creation, after setting all properties.
function edit6_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit7_Callback(hObject, eventdata, handles)
% hObject    handle to edit7 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit7 as text
%        str2double(get(hObject,'String')) returns contents of edit7 as a double


% --- Executes during object creation, after setting all properties.
function edit7_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit7 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit8_Callback(hObject, eventdata, handles)
% hObject    handle to edit8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit8 as text
%        str2double(get(hObject,'String')) returns contents of edit8 as a double


% --- Executes during object creation, after setting all properties.
function edit8_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit9_Callback(hObject, eventdata, handles)
% hObject    handle to edit9 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit9 as text
%        str2double(get(hObject,'String')) returns contents of edit9 as a double


% --- Executes during object creation, after setting all properties.
function edit9_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit9 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit10_Callback(hObject, eventdata, handles)
% hObject    handle to edit10 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit10 as text
%        str2double(get(hObject,'String')) returns contents of edit10 as a double


% --- Executes during object creation, after setting all properties.
function edit10_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit10 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit11_Callback(hObject, eventdata, handles)
% hObject    handle to edit11 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit11 as text
%        str2double(get(hObject,'String')) returns contents of edit11 as a double


% --- Executes during object creation, after setting all properties.
function edit11_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit11 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit12_Callback(hObject, eventdata, handles)
% hObject    handle to edit12 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit12 as text
%        str2double(get(hObject,'String')) returns contents of edit12 as a double


% --- Executes during object creation, after setting all properties.
function edit12_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit12 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function m_file_Callback(hObject, eventdata, handles)
% hObject    handle to m_file (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function m_file_save_Callback(hObject, eventdata, handles)
% hObject    handle to m_file_save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%保存文件
[FileName,PathName] = uiputfile({'*.jpg','JPEG(*.jpg)';
                                 '*.bmp','Bitmap(*.bmp)';
                                 '*.gif','GIF(*.gif)';
                                 '*.*',  'All Files (*.*)'},'Save Picture','Untitled');
if FileName==0
    return;
else
    h=getframe(handles.axes2);
    imwrite(h.cdata,[PathName,FileName]);
    warndlg('保存成功','保存成功');
end

hough_circle.m文件:

function [hough_space,hough_circle,para] = hough_circle(BW,step_r,step_angle,r_min,r_max,p)  
  
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
% input  
% BW:二值图像;  
% step_r:检测的圆半径步长  
% step_angle:角度步长,单位为弧度  
% r_min:最小圆半径  
% r_max:最大圆半径  
% p:阈值,0,1之间的数 通过调此值可以得到图中圆的圆心和半径  
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
% output  
% hough_space:参数空间,h(a,b,r)表示圆心在(a,b)半径为r的圆上的点数  
% hough_circl:二值图像,检测到的圆  
% para:检测到的圆的圆心、半径  
  
circleParaXYR=[];  
para=[];  
  
[m,n] = size(BW);  
size_r = round((r_max-r_min)/step_r)+1;%四舍五入  
size_angle = round(2*pi/step_angle);  
  
hough_space = zeros(m,n,size_r);  
  
[rows,cols] = find(BW);%查找非零元素的行列坐标  
ecount = size(rows);%非零坐标的个数  
  
% Hough变换  
% 将图像空间(x,y)对应到参数空间(a,b,r)  
  
% a = x-r*cos(angle)  
% b = y-r*sin(angle)  
  
for i=1:ecount  
    for r=1:size_r %半径步长数  
        for k=1:size_angle %按一定弧度把圆几等分  
            a = round(rows(i)-(r_min+(r-1)*step_r)*cos(k*step_angle));  
            b = round(cols(i)-(r_min+(r-1)*step_r)*sin(k*step_angle));  
            if(a>0&a<=m&b>0&b<=n)  
            hough_space(a,b,r) = hough_space(a,b,r)+1;%h(a,b,r)的坐标,圆心和半径  
            end  
        end  
    end  
end  
  
  
% 搜索超过阈值的聚集点。对于多个圆的检测,阈值要设的小一点!通过调此值,可以求出所有圆的圆心和半径  
max_para = max(max(max(hough_space)));%返回值就是这个矩阵的最大值  
index = find(hough_space>=max_para*p);%一个矩阵中,想找到其中大于max_para*p数的位置  
length = size(index);%符合阈值的个数  
hough_circle = false(m,n);  
%hough_circle = zeros(m,n);  
%通过位置求半径和圆心。  
for i=1:ecount  
    for k=1:length  
        par3 = floor(index(k)/(m*n))+1;  
        par2 = floor((index(k)-(par3-1)*(m*n))/m)+1;  
        par1 = index(k)-(par3-1)*(m*n)-(par2-1)*m;  
        if((rows(i)-par1)^2+(cols(i)-par2)^2<(r_min+(par3-1)*step_r)^2+5&...  
                (rows(i)-par1)^2+(cols(i)-par2)^2>(r_min+(par3-1)*step_r)^2-5)  
              hough_circle(rows(i),cols(i)) = true;   %检测的圆  
        end  
    end  
end                 
  
% 从超过峰值阈值中得到  
for k=1:length  
    par3 = floor(index(k)/(m*n))+1;%取整  
    par2 = floor((index(k)-(par3-1)*(m*n))/m)+1;  
    par1 = index(k)-(par3-1)*(m*n)-(par2-1)*m;  
    circleParaXYR = [circleParaXYR;par1,par2,par3];  
    hough_circle(par1,par2)= true; %这时得到好多圆心和半径,不同的圆的圆心处聚集好多点,这是因为所给的圆不是标准的圆  
    %fprintf(1,'test1:Center %d %d \n',par1,par2);  
end  
  
%集中在各个圆的圆心处的点取平均,得到针对每个圆的精确圆心和半径!  
while size(circleParaXYR,1) >= 1  
    num=1;  
    XYR=[];  
    temp1=circleParaXYR(1,1);  
    temp2=circleParaXYR(1,2);  
    temp3=circleParaXYR(1,3);  
    c1=temp1;  
    c2=temp2;  
    c3=temp3;  
    temp3= r_min+(temp3-1)*step_r;  
   if size(circleParaXYR,1)>1       
     for k=2:size(circleParaXYR,1)  
      if (circleParaXYR(k,1)-temp1)^2+(circleParaXYR(k,2)-temp2)^2 > temp3^2  
         XYR=[XYR;circleParaXYR(k,1),circleParaXYR(k,2),circleParaXYR(k,3)];  %保存剩下圆的圆心和半径位置  
      else    
      c1=c1+circleParaXYR(k,1);  
      c2=c2+circleParaXYR(k,2);  
      c3=c3+circleParaXYR(k,3);  
      num=num+1;  
      end   
    end  
   end   
      %fprintf(1,'sum %d %d radius %d\n',c1,c2,r_min+(c3-1)*step_r);  
      c1=round(c1/num);  
      c2=round(c2/num);  
      c3=round(c3/num);  
      c3=r_min+(c3-1)*step_r;  
      %fprintf(1,'num=%d\n',num)  
      %fprintf(1,'Center %d %d radius %d\n',c1,c2,c3);     
      para=[para;c1,c2,c3]; %保存各个圆的圆心和半径的值  
      circleParaXYR=XYR;  
end 

以上完整源码仅供参考,此次任务小组合作完成,所以博主对以上代码一些部分不是很了解,谢谢合作。

2016-04-26 16:46:27 jsgaobiao 阅读数 22353

代码下载:http://download.csdn.net/detail/jsgaobiao/9503229

 

Ø  【作业要求】


Write your own imfindcircles() to simulatematlab function imfindcircles(). The attached images are for testing.

Submit your code, result and report.


Ø  【文件说明】


main.m:

读取3张测试图片并且进行转灰度图、用Sobel算子边缘检测、二值化、调用findcircle函数并将找到的圆绘制在原图上。

findcircle.m:

利用霍夫变换的方法找到图片中的圆,并返回圆的坐标和半径。


Ø  【作业思路】


本次作业找圆主要是使用了霍夫变换的方法。

先介绍一下霍夫变换的思想:


霍夫变换是图像处理中用于识别几何图形的一种常用方法。最简单的应用是检测黑白图像上的一条直线。我们用y=kx+b表示一条直线,其中k和b是参数,分别是斜率和截距。如果将k和b视为变量,考虑参数平面k-b,那么x-y平面上的一个点对应到k-b参数平面上就是一条直线。

假设在x-y平面上有若干待拟合的散点,那么他们可以对应到参数平面上的若干条直线。如果x-y平面上的散点都在一条直线上,那么他们对应在参数平面上的若干条直线必然交与(k0,b0)这一点,其中k0,b0是x-y平面上那条直线的参数。如果参数平面上的直线产生了多个交点,那么我们就选取经过直线最多的交点。可以理解为若干直线对于坐标点(k,b)的投票,票数最多的参数(k,b)我们认为就是最好的一组参数。


处理圆的情况更容易理解,因为我们可以取和图像平面一样的参数平面,以图像上的每一个非零点(因为该算法处理的是二值化后的图片,即对原图进行边缘提取后的结果)为圆心,以已知的半径在参数平面上画圆(对圆覆盖的坐标点进行投票),最后找出参数平面上的峰值,就对应于原图中的圆心。

但是这个做法存在一个问题——我们并不知道圆的半径。一个解决方案是把参数平面拓展为三维的空间x-y-r,对应圆心坐标和半径。这样做需要增加相当大的时间、空间复杂度。为了提高算法的效率,我将圆的半径范围作为参数输入findcircle函数中,对于不同的图像采用不同的参数进行处理,可以有效的减少运行的时间。

 

另外,作为参数输入findcircle函数的还有二值化后的图像BW,枚举半径的范围[minR,maxR]和步长stepR和在参数平面画圆投票的弧度步长stepAngle。

最终的检测效果如下图所示:

2013-09-23 11:02:31 johnhany 阅读数 8166

      在图像处理中,Hough变换(霍夫变换)主要用来识别已知的几何形状,最常见的比如直线、线段、圆形、椭圆、矩形等。如果要检测比较复杂的曲线图形,就需要利用广义霍夫变换。


      霍夫变换的原理是根据参数空间的统计规律进行参数估计。

      具体说来就是,将直角坐标系中的图形(x,y)变换到参数空间(k1,...,kn),对直角坐标系中的每一个像素点,计算它在参数空间里的所有可能的参数向量。处理完所有像素点后,把出现次数(频率)最多的(一个或几个)参数向量的坐标作为参数代入直角坐标方程,即检测到的图形方程。


      以直线检测为例,详细讲一下步骤:(圆和直线的原理相同,只是直线的公式比较好打~)

      1.图像二值化,待检测的线变为黑色,背景置为白色。既然是形状检测,这步是必不可少的。

      2.假设直线的参数方程为p=x*cosa+y*sina,对于直线上的某个点(x,y)来说,变换到参数空间的坐标就是(p,a),而且这条直线上的所有点都对应于(p,a)。对于一个固定点(x,y)来说,经过它的直线系可以表示为p=(x^2+y^2)^1/2*sin(a+b),其中tanb=x/y,对应参数空间里的一条正弦曲线。也就是说,图像中的一条直线对应参数空间的一点,图像中的一点对应参数空间的一条正弦曲线。


      关于参数变换,我再白话几句。如果直线方程写成y=k*x-b,则对应于参数空间里的点(k,-b),这就有点像图论中的对偶变换了。在写图的程序时有时会遇到若干半平面求交的问题(整张平面被一条直线分割后得到两张半平面)。半平面求交关键在于找到求交后的边界(如果交集非空),既可以使用递增式算法(在已经找到的一部分边界基础上引入下一张半平面的直线求下一步的边界),也可以使用上面提到的参数变换方法。

      比如我想求几张方向都朝上(y轴正方向)的半平面的交,我想得到的应该是一个下侧以向下凸的折线为边界的上侧无穷的区域。我的问题关键在于找到这条下凸的折线。直线y=k*x-b做参数变换,得到点(k,-b),所有半平面的边界直线经变换得到若干个点。这些点形成的点集存在一个凸包(包含点集的最小凸多边形,而且该多边形每个顶点都来自点集),其中构成折线的直线所对应的点恰好是凸包的上半部分,也就是“下包络”变换成上凸包。而求点集的上凸包可是很简单的(也是增量式算法)。


      3.把参数空间分割为n*m个格子,得到参数矩阵,矩阵元(pi,aj)的初始值均为0,用来对参数计数。计数值代表这个参数是最终结果的可能性,计数值越大,说明落在这条直线上的像素点越多,也就说明它越有可能是我们想找到的参数。p的范围可以是[0,图像对角线长度],a的范围可以是[0,PI/2](如果取左上角为原点的话),但要包含整个图像。

      4.按照栅格顺序扫描图像,遇到黑色像素就做如下操作:

        pi的i从0取到n-1,对每一个pi,把它和像素点的坐标(x,y)代入参数方程,计算得到相应的ai,如果ai在定义域范围内(或者在图像内),将矩阵元(pi,ai)加一。

        处理完所有像素后,如果想识别d条直线,就在参数矩阵中找到前d个数值最大的矩阵元,他们的坐标作为方程参数,在直角坐标系绘制出直线就可以了。


      OpenCV中提供了计算霍夫变换的库函数HoughLinesHoughLinesP,想知道怎样使用,请戳传送门


      圆形检测的过程很类似,只是参数方程有变化,而且参数空间增加了一个维度(圆心坐标x,y和半径r)。

      霍夫变换的一个好处就是不需要图像中出现完整的圆,只要落在一个圆上的像素数量足够多,就能正确识别。


      关于误差的问题:如果待检测像素没有严格落在同一个圆上,比如构成圆的圆弧彼此有些错位,如果依据参数点最多准则,只会识别出弧长最长的圆弧而忽略其他本来也属于同一个圆的圆弧。如果目标是检测不止一个圆,这种误差可能会使得程序依据同一个圆上的几个圆弧识别到几个不同的圆。解决这个问题一种方法是仍然采用参数点最多准则,但减小参数空间分割的份数,让错位圆弧的圆心落在同一个参数矩阵元上,但这样做会使检测到的圆心位置有比较大的误差。另一种方法是仍然把参数空间细密分割,用聚类算法寻找可能的圆心,因为错位圆弧的圆心彼此靠得很近而且计数值都很大,只要找到这些点的外接圆圆心就可以了。


      下面为了计算简便,我给出只检测一个半径为100的圆形的代码(要想采用聚类算法,只需修改第71-81行的代码块):

#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include <math.h>

#define X_MAX 400
#define Y_MAX 400
#define TO_BE_BLACK 40

//radius of circles is known
int houghTrans_r(IplImage *src, IplImage *dst, IplImage *tmp, float r, int xstep, int ystep)
{
	int width = src->width;
	int height = src->height;

	int channel = src->nChannels;
	int xmax = width%xstep ? width/xstep+1 : width/xstep;
	int ymax = height%ystep ? height/ystep+1 : height/ystep;

	int i,j,x,y;
	int para[X_MAX][Y_MAX] = {0};

	//i,j are in the pixel space
	//x,y are in the parameter space
	for(j=0; j<height; j++)
	{
		uchar* pin = (uchar*)(src->imageData + j*src->widthStep);
		for(i=0; i<width; i++)
		{
			//pixel is black
			if(pin[channel*i] < TO_BE_BLACK)
			{
				float temp;

				//calculate every probable y-cord based on x-cord
				for(x=0; x<xmax; x++)
				{
					temp = r*r - (i-x*xstep)*(i-x*xstep);
					temp = sqrt(temp);

					y = j - (int)temp;
					if(y>=0 && y<height){
						para[x][y/ystep]++;
					}

					y = j + (int)temp;
					if(y>=0 && y<height){
						para[x][y/ystep]++;
					}
				}
			}
		}
	}

	//find circle in parameter space
	int paramax=0,findx=-1,findy=-1;
	for(y=0; y<ymax; y++)
	{
		for(x=0; x<xmax; x++)
		{
			if(para[x][y] > paramax)
			{
				paramax=para[x][y];
				findx=x;
				findy=y;
			}
		}
	}

	//draw the parameter space image
	int ii,jj;
	for(y=0; y<ymax; y++)
	{
		uchar* pout = (uchar*)(tmp->imageData + y*tmp->widthStep);
		for(x=0; x<xmax; x++)
		{
			pout[channel*x]=para[x][y]*255/paramax;
			pout[channel*x+1]=para[x][y]*255/paramax;
			pout[channel*x+2]=para[x][y]*255/paramax;
		}
	}

	//draw the found circle
	if(findx>=0 && findy>=0)
	{
		for(j=0;j<height;j++)
		{
			uchar* pin=(uchar*)(src->imageData+j*src->widthStep);
			uchar* pout=(uchar*)(dst->imageData+j*dst->widthStep);
			for(i=0;i<width;i++)
			{
				pout[3*i]=128+pin[3*i]/2;
				pout[3*i+1]=128+pin[3*i+1]/2;
				pout[3*i+2]=128+pin[3*i+2]/2;
			}
		}
		cvCircle(dst,cvPoint(findx*xstep+xstep/2.0,findy*ystep+ystep/2.0),r,cvScalar(255,0,0),1,8,0);
	}

	return 1;
}

int main()
{
	IplImage *srcImg=cvLoadImage("H:\circle_4.jpg");
	cvNamedWindow("Src",CV_WINDOW_AUTOSIZE);
	cvNamedWindow("Result",CV_WINDOW_AUTOSIZE);
	cvNamedWindow("Temp",CV_WINDOW_AUTOSIZE);

	IplImage *houghImg = cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_8U,3);
	IplImage *houghTmp = cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_8U,3);
	
	houghTrans_r(srcImg,houghImg,houghTmp,100.0,1,1);

	cvShowImage("Src",srcImg);
	cvShowImage("Temp",houghTmp);
	cvShowImage("Result",houghImg);

	cvWaitKey(0);
	cvReleaseImage(&srcImg);
	cvReleaseImage(&houghImg);

	cvDestroyWindow("Src");
	cvDestroyWindow("Result");
	return 0;
}

      以下是检测示例:(左中右分别为原图像、参数空间图像和检测结果,检测结果用蓝色线绘制)

         由于固定半径r,所以参数就是圆心位置(x,y),绘制的点代表圆心的可能位置,颜色越浅,可能性越大。


        检测单独的圆



        在很乱的线中检测不完整的圆



        检测彼此错位的圆弧(参数划分扩大为5*5)


没有更多推荐了,返回首页