霍夫變換
霍夫變化 :(Hough Transform)是圖像處理中的一種特徵提取技術,在一個參數空間中通過計算累計結果的局部最大值(累計局部最大值) 得到一個符合該特定形狀的集合作爲霍夫變換的結果;
霍夫變換主要分爲兩種: 霍夫直線變換與霍夫圓變換;
1、標準霍夫變換;HoughLines()
2、多尺度霍夫變換;HoughLines()
3、累計霍夫變換;HoughLineP()
4、霍夫圓變換 : HoughCircles()
霍夫線變換
1、霍夫變換輸入一般爲邊緣二值圖,用以尋找輪廓中的直線、圓;
2、霍夫線變換可分爲:標準霍夫變換、多尺度霍夫變換、累計概率霍夫變換3種;
3、霍夫線變換的原理爲:線性座標系與極座標之間的轉換;
4、HoughLines參數說明:
src : 輸入圖像,一般爲8位單通道二值圖像;
lines : 線條輸出矢量(極座標表示形式:(ρ,θ)),EmguCV中可以用VectorOfPointF類型存儲,x座標存儲ρ值,y座標存儲θ值;
rho : 像素掃描步長(ρ);
theta : 角度掃描步長(θ);
threshold:設定有足夠交點數的極座標才認爲是直線;
srn,stn : 多尺度霍夫變換使用;
5、累計霍夫變換:EmguCV提供了兩種封裝方法,方法1返回值爲空,計算直線點通過方法參數輸出;方法2返回值爲LineSegment2D類型,直線點座標返回輸出;
使用第一種方法,可以使用VectorOfRect類型存儲計算座標點:
Hough線變換Demo
1、HoughLines()計算的座標點輸出爲極座標點,需要自己換算到直角座標系;
2、HoughLineP()計算輸出爲直線的兩端點,不需要自己換算;
3、閾值,最低線段長度,允許連接最大距離影響實際作用效果;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using System.Drawing;
namespace lesson18
{
class Program
{
static void Main(string[] args)
{
//Mat src = CvInvoke.Imread("1.bmp");
//Mat grayimg = new Mat();
//Mat edge = new Mat();
//CvInvoke.CvtColor(src, grayimg, ColorConversion.Bgr2Gray);
//CvInvoke.Canny(grayimg, edge, 100, 200, 3, false);
//CvInvoke.Imshow("canny image", edge);
//VectorOfPointF lines = new VectorOfPointF(); //lines存儲的是極座標值
//CvInvoke.HoughLines(edge, lines, 10, Math.PI / 180, 600, 0, 0);
//for(int i = 0; i < lines.Size; i++)
//{
// float rho = lines[i].X; //將極座標值轉換到線座標系中
// float theta = lines[i].Y;
// double a = Math.Cos(theta), b = Math.Sin(theta);
// double x0 = rho * a, y0 = rho * b; //線座標系中對應的點
// Point pt1 = new Point();
// Point pt2 = new Point();
// pt1.X = (int)Math.Round(x0 + 1000 * (-b)); //求取對應點上下兩點的座標,1000爲線距
// pt1.Y = (int)Math.Round(y0 + 1000 * a);
// pt2.X = (int)Math.Round(x0 - 1000 * (-b));
// pt2.Y = (int)Math.Round(y0 - 1000 * a);
// CvInvoke.Line(src, pt1, pt2, new MCvScalar(0, 0, 255), 2, LineType.EightConnected);
//}
//CvInvoke.Imshow("hough test", src);
///累計霍夫變換
Mat src = CvInvoke.Imread("mask.jpg");
Mat grayimg = new Mat();
Mat cannyimg = new Mat();
CvInvoke.CvtColor(src, grayimg, ColorConversion.Bgr2Gray);
CvInvoke.Canny(grayimg, cannyimg, 100, 200, 3, false);
LineSegment2D[] lines = CvInvoke.HoughLinesP(cannyimg, 10, Math.PI / 180, 30, 5, 10); //累計霍夫變換自動計算出直線的兩端點
for(int i = 0; i < lines.Length;i++)
{
Point pt1 = lines[i].P1; //直線兩端點
Point pt2 = lines[i].P2;
CvInvoke.Line(src, pt1, pt2, new MCvScalar(0, 255, 0), 2, LineType.EightConnected);
}
CvInvoke.Imshow("hough test", src);
CvInvoke.WaitKey(0);
}
}
}
標準Hough 線變換
累計霍夫線變換:
Hough圓變換
1、OpenCV/EmguCV中使用霍夫梯度法進行圓檢測;
2、API : HoughCircles()
,
參數說明:
circles : CircleF類型參數;
method : 方法,只支持霍夫梯度法;
dp : 1 : 原圖搜索,2 : 取圖像一半搜索;
param1 : 傳遞給Canny算子的高閾值;
param2 : 中心點累加器閾值(圓心最少有多少次重合才認爲是一個圓);
minRadius,maxRadius : 檢測的 最大最小圓範圍
Hough圓變換Demo
1、參數取值直接影響實驗效果
...
Mat src = CvInvoke.Imread("2.png");
Mat dst = Mat.Zeros(src.Rows,src.Cols,DepthType.Cv8U,3);
Mat grayimg = new Mat();
CvInvoke.CvtColor(src, grayimg, ColorConversion.Bgr2Gray);
CvInvoke.Imshow("input", grayimg);
CircleF[] circles = CvInvoke.HoughCircles(grayimg, HoughType.Gradient, 1, 30, 100, 30, 10, 200); //minRadius設置爲100,則所有圓都被過濾
//CircleF[] circles = CvInvoke.HoughCircles(grayimg, HoughType.Gradient, 1, 80, 200, 30, 120, 200);
for (int i = 0; i < circles.Length; i++)
{
CvInvoke.Circle(dst, new Point((int)circles[i].Center.X, (int)circles[i].Center.Y), (int)circles[i].Radius,
new MCvScalar(255, 255, 0), 3, LineType.EightConnected);
}
CvInvoke.Line(dst, new Point(10, 10), new Point(100, 100),new MCvScalar(127,127,0),2);
CvInvoke.Imshow("hough circle test", dst);
CvInvoke.WaitKey(0);