2019-03-28 10:54:18 guohaoxin 阅读数 1520

加载图像

该示例使用带有各种颜色的圆形塑料片的图像。如图1所示。
图1

rgb = imread('DetectCirclesExample_01.png');%读入图片
imshow(rgb)%显示图

除了有足够的圆形可以检测外,这个图像中对圆形的检测时还有一些有趣的事情:

  1. 存在不同颜色的芯片,其与背景具有不同的对比度。 一方面,蓝色和红色在这个背景上有强烈的对比。 另一方面,一些黄色芯片与背景对比较差;
  2. 可以发现一些芯片是相互叠加的,还有一些芯片是靠近在一起并且几乎相互接触的。 重叠对象边界和对象的遮挡通常是对象检测的挑战。

确定搜索圈的半径范围

imfindcircles函数需要一个半径范围来搜索圆圈。 找到合适的半径范围的快速方法是使用交互式工具imdistline来获得各种对象半径的近似估计。如图2所示。
图2

d = imdistline;%显示交互式工具,测量半径

imdistline创建了一个可拖动的工具,可以移动以适应芯片,并且可以读取数字以获得其半径的近似估计。 大多数芯片的半径范围为20像素。 使用稍大的20-25像素的半径范围以确保可以检测到足够多的芯片。 注意在进行下一步操作之前需要删除imdistline工具。

delete(d)%删除交互式工具

初步尝试查找圆形

在此图像上调用imfindcircles,搜索半径为[20 25]像素。 在此之前,最好查看物体是否比背景更亮或更暗。 要查看图像的暗亮程度,可以调取此图像的灰度版本
背景非常明亮,大多数芯片比背景更暗。 但是,默认情况下,imfindcircles会找到比背景更亮的圆形对象。 因此,在imfindcircles中将参数’ObjectPolarity’设置为’dark’以搜索比背景暗的图像。

gray_image = rgb2gray(rgb);%图像的灰度版本
imshow(gray_image)%显示图像
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark');%查找圆形

得到对的结果如下:

centers =[ ]
radii =[ ]

请注意,输出中心位置和半径为空,这意味着没有找到圆圈。 这种情况经常发生,因为imfindcircles是一个圆形探测器,与大多数探测器类似,imfindcircles有一个内部探测阈值,决定了它的灵敏度。 简单来说,这意味着检测器对某个(圆形)检测的置信度必须大于某个水平才能被认为是有效检测
imfindcircles有一个参数’Sensitivity’,可用于控制此内部阈值,从而控制算法的灵敏度。 较高的“灵敏度”值会将检测阈值设置得较低,从而导致检测到更多圆圈。

提高检测灵敏度

回到圆形图像,有可能在默认的灵敏度水平下,所有圆都低于内部阈值,这就是没有检测到圆的原因。 默认情况下,“灵敏度”(0到1之间的数字)设置为0.85。 将“敏感度”提高到0.9。

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.9)

这次imfindcircles发现了一些圆圈 - 准确地说是5个圆圈,如图3。 中心包含圆心的位置,半径包含这些圆的估计半径。

在图像上绘制圆圈

函数viscircles可用于在图像上绘制圆圈。 来自imfindcircles的输出变量中心和半径可以直接传递给viscircles。

imshow(rgb)
h = viscircles(centers,radii);

图3圆心被正确定位,其相应的半径似乎与实际芯片很好地匹配。 但仍有不少圆形被遗漏。 尝试将“灵敏度”提高到0.92。

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.92);
length(centers)

因此,增加“灵敏度”会让我们得到更多的圆形。 再次在图像上绘制这些圆形,如图4。

delete(h)  % Delete previously drawn circles
h = viscircles(centers,radii);

图4

使用第二种方法(两阶段)寻找圆圈

这个结果看起来更好。 imfindcircles有两种不同的方法来寻找圆圈。 到目前为止,称为相位编码方法的默认方法用于检测圆。 还有另一种方法,通常称为两阶段方法,可以在imfindcircles中使用。 使用两阶段方法并显示结果。

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.92,'Method','twostage');
delete(h)
h = viscircles(centers,radii);

两阶段方法检测更多圆,灵敏度为0.92。 通常,这两种方法是互补的,因为它们具有不同的强度。 与两阶段方法相比,相位编码方法通常更快并且对噪声更加鲁棒。 但它也可能需要更高的“灵敏度”水平来获得与两阶段方法相同数量的检测。 例如,如果将“灵敏度”级别提高到更高,相位编码方法也会找到相同的芯片,比如0.95,结果如图5所示。

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.95);
delete(h)
viscircles(centers,radii);

图5
请注意,imfindcircles中的两种方法都能准确地找到部分可见(遮挡)芯片的中心和半径。

为什么有些圈子仍然被错过?

看看最后的结果,很奇怪imfindcircles没有在图像中找到黄色芯片。 黄色芯片与背景没有强烈的对比。 事实上,它们似乎与背景具有非常相似的强度。 是否有可能黄色芯片并不像假设的那样真正“背景”更暗? 要确认,请再次显示此图像的灰度版本。

imshow(gray_image)

在图像中找到“明亮”的圆圈

与背景相比,黄色芯片的强度几乎相同,甚至更亮。 因此,要检测黄色芯片,请将“ObjectPolarity”更改为“bright”。

[centersBright,radiiBright] = imfindcircles(rgb,[20 25], ...
'ObjectPolarity','bright','Sensitivity',0.92);

绘制不同颜色的“明亮”圆圈

通过更改viscircles中的“Color”参数,以不同的颜色绘制明亮的圆圈。
请注意,发现了三个缺失的黄色芯片,但仍然缺少一个黄色芯片,如图6所示。这些黄色芯片很难找到,因为它们在这种背景下并不像其他芯片那样突出。
图6

降低’EdgeThreshold’的值

imfindcircles中还有另一个参数可能在这里很有用,即’EdgeThreshold’。要查找圆圈,imfindcircles仅使用图像中的边缘像素。这些边缘像素基本上是具有高梯度值的像素。 “EdgeThreshold”参数控制像素的梯度值在被视为边缘像素并包含在计算中之前必须有多高。此参数的高值(接近1)将仅允许包含强边(更高的梯度值),而低值(更接近0)更宽松,甚至包括更弱的边(更低的梯度值)计算。在缺少黄色芯片的情况下,由于对比度低,所以预期一些边界像素(在芯片的圆周上)具有低梯度值。因此,降低“EdgeThreshold”参数以确保黄色芯片的大部分边缘像素都包含在计算中,如图7所示。
图7

[centersBright,radiiBright,metricBright] = imfindcircles(rgb,[20 25], ...
'ObjectPolarity','bright','Sensitivity',0.92,'EdgeThreshold',0.1);
delete(hBright)
hBright = viscircles(centersBright, radiiBright,'Color','b');

一起绘制“黑暗”和“明亮”圆圈

h = viscircles(centers,radii);

现在,imfindcircles找到所有黄色的,绿色的。 用蓝色绘制这些圆形,以及之前发现的其他圆形(“ObjectPolarity”设置为“dark”),如图8所示。
图8
应该注意的是,将参数更改为在检测中更容易可能会发现更多的圆圈,但它也增加了检测假圆的可能性。 可以找到的真实圆圈数(检测率)和与它们一起找到的假圆圈数量之间存在权衡(误报率)

完整代码

%% Step 1: Load Image
rgb = imread('DetectCirclesExample_01.png');
imshow(rgb)
%% Step 2: Determine Radius Range for Searching Circles
d = imdistline;
delete(d)
%%  Step 3: Initial Attempt to Find Circles
gray_image = rgb2gray(rgb);
imshow(gray_image)
[centers,radii] = imfindcircles(rgb,[35 43],'ObjectPolarity','dark');
%% Step 4: Increase Detection Sensitivity
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.9);
Step 5: Draw the Circles on the Image
imshow(rgb)
h = viscircles(centers,radii);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.92);
length(centers)
delete(h)  % Delete previously drawn circles
h = viscircles(centers,radii);
%% Step 6: Use the Second Method (Two-stage) for Finding Circles
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.92,'Method','twostage');
delete(h)
h = viscircles(centers,radii);
[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.95);
delete(h)
viscircles(centers,radii);
%% Step 7: Why are Some Circles Still Getting Missed?
imshow(gray_image)
%% Step 8: Find 'Bright' Circles in the Image
[centersBright,radiiBright] = imfindcircles(rgb,[20 25], ...
'ObjectPolarity','bright','Sensitivity',0.92);
%% Step 9: Draw 'Bright' Circles with Different Color
imshow(rgb)
hBright = viscircles(centersBright, radiiBright,'Color','b');
%% Step 10: Lower the Value of 'EdgeThreshold'
[centersBright,radiiBright,metricBright] = imfindcircles(rgb,[20 25], ...
'ObjectPolarity','bright','Sensitivity',0.92,'EdgeThreshold',0.1);
delete(hBright)
hBright = viscircles(centersBright, radiiBright,'Color','b');
%% Step 11: Draw 'Dark' and 'Bright' Circles Together
h = viscircles(centers,radii);

github

具体内容及代码下载见HaoxinGuo

2019-09-30 21:35:38 qq_41413256 阅读数 40

目标检测(object detection)

目标检测的目的

目标检测是找到图像中感兴趣的目标(物体),确定他们的位置和大小。我的理解就是将目标图中的物体用算法(传统算法或则是基于深度学习的算法)实现,用一个个的框框框出来,然后识别框框中的物体是什么,也是为下一的目标识别做准备。
机器视觉中的图像处理有四大任务:

  1. 分类(classification):假定给定一幅图像或者一段视频,要判断里面有什么类别的目标。
  2. 定位(location):定位出目标的位置,一般用边框将物体圈出来。
  3. 检测(detection):定位出目标的位置并检测出目标是什么。

传统的目标检测方法

  1. Viola-Jones(VJ):采用积分图特征+AdaBoost方法进行人脸检测等。
  2. HOG+SVM用于行人检测,通过对行人目标候选区域提取HOG特征,结合SVM分类器进行判定。
  3. DPM:基于HOG特征检测的一个变种,该方法是非深度学习方法中检测效果最好,性能最优的。

基于深度学习的目标检测

  1. One-stageYOLO和SSD系列):直接回归初目标框位置,不用产生候选框。
  2. Two-stageFaster RCNN系列):利用RPN网络对候选框进行推荐。
    上面写了一大堆,其实我也不是很清楚要做什么,这只是一个概述,方便我今后学习用的。就酱
2018-10-03 15:46:39 u013921430 阅读数 4095

【fishing-pan:https://blog.csdn.net/u013921430 转载请注明出处】

灰度图边缘检测

   在学习图像处理时,首先接触到的就是灰度图像的边缘检测,这是图像处理最基础的也是最重要的一环,熟悉图像边缘检测有助于我们学习其他的数字图像处理方法。由于图像的边缘区域会存在明显的像素值阶跃,因此边缘检测主要是通过获得图像灰度梯度,进而通过梯度大小和变化来判断图像边缘的。
  
在这里插入图片描述
   因此,我们可以通过一阶差分;
Δfx(x,y)=f(x+1,y)f(x,y)Δfy(x,y)=f(x,y+1)f(x,y) \Delta f_{x}(x,y)=f(x+1,y)-f(x,y)\\ \Delta f_{y}(x,y)=f(x,y+1)-f(x,y)
   或者二阶差分对边缘区域进行判断;
Δfxx(x,y)=f(x+1,y)+f(x1,y)2f(x,y)Δfyy(x,y)=f(x,y+1)+f(x,y1)2f(x,y) \Delta f_{xx}(x,y)=f(x+1,y)+f(x-1,y)-2f(x,y)\\ \Delta f_{yy}(x,y)=f(x,y+1)+f(x,y-1)-2f(x,y)
   其中一阶差分可以判断边缘是否存在,二阶差分还可以根据正负号判断像素点在图像边缘亮的一侧还是暗的一侧。
   其他的边缘检测方法还包括一些梯度算子,例如Prewitt算子、Sobel算子,Canny算子,LOG边缘检测算子等,在此不做说明。

彩色图边缘检测

   RGB 图像使用三个通道存储像素信息,我们可以将这三个通道的信息看作是一个矢量,而矢量是不存在梯度的概念的,我们无法直接将上诉方法或算子直接用于RGB 图像,而且RGB图像单个通道的梯度信息又无法反映整体的梯度信息。
   在《数字图像处理》(冈萨雷斯)中提到了一种针对彩色图像的边缘检测方法,这种方法由 Di Zenzo 等人在1986年提出,下面就一起看看这种方法如何得出。

Di Zenzo’s gradient operator

   在图像多通道图像f(x,y)f(x,y) 中的某一点P(x,y)P(x,y) 处,假设其梯度方向为θ\theta
Δf=f(x+εcosθ,y+εsinθ)f(x,y) \Delta f=\left \| f(x+\varepsilon cos\theta,y+\varepsilon sin\theta) -f(x,y)\right \|
   为了便于计算,将计算绝对值换为计算平方,令
Δf2=f(x+εcosθ,y+εsinθ)f(x,y)2 \Delta f^{2}=\left \| f(x+\varepsilon cos\theta,y+\varepsilon sin\theta) -f(x,y)\right \|^{2}
   对f(x+εcosθ,y+εsinθ)f(x+\varepsilon cos\theta,y+\varepsilon sin\theta)进行二元泰勒展开;
f(x+εcosθ,y+εsinθ)=f(x,y)+i=1m(εcosθfi(x,y)x+εsinθfi(x,y)y)+onf(x,y)+i=1m(εcosθfi(x,y)x+εsinθfi(x,y)y) \begin{aligned} f(x+\varepsilon cos\theta,y+\varepsilon sin\theta)&=f(x,y)+\sum_{i=1}^{m}(\varepsilon cos\theta\cdot\frac{\partial f_{i}(x,y)}{\partial x} +\varepsilon sin\theta\cdot\frac{\partial f_{i}(x,y)}{\partial y} )+o^{n}\\ &\approx f(x,y)+\sum_{i=1}^{m}(\varepsilon cos\theta\cdot\frac{\partial f_{i}(x,y)}{\partial x} +\varepsilon\cdot sin\theta\cdot\frac{\partial f_{i}(x,y)}{\partial y} ) \end{aligned}
   其中mm表示图像通道数目,为了方便表述使用fix\frac{\partial f_{i}}{\partial x}代替fi(x,y)x\frac{\partial f_{i}(x,y)}{\partial x},而在求导时各个通道之间是相互独立的,则有;
Δf2i=1m(εcosθfix+εsinθfiy)2 \Delta f^{2}\approx\sum_{i=1}^{m}(\varepsilon cos\theta\cdot\frac{\partial f_{i}}{\partial x} +\varepsilon sin\theta\cdot\frac{\partial f_{i}}{\partial y} )^{2}
  重新定义一个函数G(θ)G(\theta),令
G(θ)=i=1m(εcosθfix+εsinθfiy)2=ε2(cosθ2i=1mfix2+sinθ2i=1mfiy2+2sinθcosθi=1mfixfiy) \begin{aligned} G(\theta)&=\sum_{i=1}^{m}(\varepsilon cos\theta\cdot\frac{\partial f_{i}}{\partial x} +\varepsilon sin\theta\cdot\frac{\partial f_{i}}{\partial y} )^{2}\\ &=\varepsilon ^{2}(cos\theta^{2}\sum_{i=1}^{m}\left \|\frac{\partial f_{i}}{\partial x}\right \|^{2}+sin\theta^{2}\sum_{i=1}^{m}\left \|\frac{\partial f_{i}}{\partial y}\right \|^{2}+2sin\theta cos\theta \sum_{i=1}^{m}\frac{\partial f_{i}}{\partial x}\frac{\partial f_{i}}{\partial y}) \end{aligned}
   进一步舍去式子中的ε\varepsilon 项,令
G(θ)=cosθ2i=1mfix2+sinθ2i=1mfiy2+2sinθcosθi=1mfixfiy G(\theta)=cos\theta^{2}\sum_{i=1}^{m}\left \|\frac{\partial f_{i}}{\partial x}\right \|^{2}+sin\theta^{2}\sum_{i=1}^{m}\left \|\frac{\partial f_{i}}{\partial y}\right \|^{2}+2sin\theta cos\theta \sum_{i=1}^{m}\frac{\partial f_{i}}{\partial x}\frac{\partial f_{i}}{\partial y}
   为了进一步方便表述;令
E=i=1mfix2;F=i=1mfiy2;H=i=1mfixfiy E=\sum_{i=1}^{m}\left \| \frac{\partial f_{i}}{\partial x} \right \|^{2}; F=\sum_{i=1}^{m}\left \|\frac{\partial f_{i}}{\partial y}\right \|^{2}; H=\sum_{i=1}^{m}\frac{\partial f_{i}}{\partial x}\frac{\partial f_{i}}{\partial y}
G(θ)=cosθ2E+sinθ2F+2sinθcosθH G(\theta)=cos\theta^{2}E+sin\theta^{2}F+2sin\theta cos\theta H
   现在θ\theta成为了式子中唯一的变量,再回到边缘的定义上,边缘的方向是图像像素梯度最大的方向。也就是说梯度的方向θmax\theta_{max} 会使G(θ)G(\theta) 取最大值,则;
θmax=G(θ)argmax \theta_{max}=\underset{argmax}{G(\theta )}
   对G(θ)G(\theta) 进行求导;
G(θ)=Esin2θ+Fsin2θ+2Hcos2θ G(\theta )^{'}=-Esin2\theta +F sin2\theta+2 H cos2\theta
   令G(θ)=0G(\theta )^{'}=0,得;
tan 2θmax=2HEFθmax=12arctan(2HEF+kπ) tan ~2\theta_{max} =\frac{2H}{E-F}\\ \theta_{max}=\frac{1}{2}arctan(\frac{2H}{E-F}+k\pi)
   很明显G(θ)G(\theta ) 是一个以π\pi 为周期的周期函数,如果只考虑区间[0,π)\left [ 0 ,\pi\right ),且θmax\theta_{max} 落到该区间内,则会有另一个让G(θ)G(\theta )取极值的解也落在该区域内,这个值是θmax+π2\theta_{max}+ \frac{\pi}{2}或者θmaxπ2\theta_{max}-\frac{\pi}{2}。但是不论如何这两个解有一个让G(θ)G(\theta )取极大值,另一个让其取极小值,两个角度相差 90°。
  
   说到这里大家应该都明白了,两个角度对应的方向是相互垂直的,一个是垂直于边缘的方向,也就是边缘的法向,此时梯度取最大值。另一个是平行于边缘的方向,是边缘的切向,此时梯度取极小值。
  

RGB图像的边缘检测

   在RGB图像中,m=3m=3,再令;
u=Rxr+Gxg+Bxb \overset{\rightarrow }{u}=\frac{\partial R}{\partial x}\overset{\rightarrow }{r}+\frac{\partial G}{\partial x}\overset{\rightarrow }{g}+\frac{\partial B}{\partial x}\overset{\rightarrow }{b}
v=Ryr+Gyg+Byb \overset{\rightarrow }{v}=\frac{\partial R}{\partial y}\overset{\rightarrow }{r}+\frac{\partial G}{\partial y}\overset{\rightarrow }{g}+\frac{\partial B}{\partial y}\overset{\rightarrow }{b}
   其中r\overset{\rightarrow }{r}g\overset{\rightarrow }{g}b\overset{\rightarrow }{b}分别代表不同颜色分量的单位向量,则
gxx=E=uTu=Rx2+Gx2+Bx2 g_{xx}=E=\overset{\rightarrow }{u}^{\tiny{T}}\overset{\rightarrow }{u}=\left \| \frac{\partial R}{\partial x} \right \|^{2}+\left \| \frac{\partial G}{\partial x} \right \|^{2}+\left \| \frac{\partial B}{\partial x} \right \|^{2}
gyy=F=vTv=Ry2+Gy2+By2 g_{yy}=F=\overset{\rightarrow }{v}^{\tiny{T}}\overset{\rightarrow }{v}=\left \| \frac{\partial R}{\partial y} \right \|^{2}+\left \| \frac{\partial G}{\partial y} \right \|^{2}+\left \| \frac{\partial B}{\partial y} \right \|^{2}
gxy=H=uTv=RxRy+GxGy+BxBy g_{xy}=H=\overset{\rightarrow }{u}^{\tiny{T}}\overset{\rightarrow }{v}=\frac{\partial R}{\partial x}\frac{\partial R}{\partial y}+\frac{\partial G}{\partial x}\frac{\partial G}{\partial y}+\frac{\partial B}{\partial x}\frac{\partial B}{\partial y}
   在利用Di Zenzo 提出的方法求得θmax\theta_{max} 后,将以上符号带入到G(θ)G(\theta),可以计算出像素点梯度大小为
G(θ)={12[(gxx+gyy)+(gxxgyy)cos 2θmax+2gxysin 2θmax]}12 G(\theta)=\left \{ \frac{1}{2}\left [ (g_{xx}+g_{yy}) +(g_{xx}-g_{yy})cos~2\theta_{max} +2g_{xy}sin~2\theta_{max} \right ]\right \}^{\frac{1}{2}}
   进而可以根据梯度大小进行边缘检测。

参考资料

  1. S. Di Zenzo, A note on the gradient of a multi-image, Computer Vision, Graphics, and Image Processing 33 (1) (1986) 116–125.
  2. 《数字图像处理》 (冈萨雷斯)
2018-04-18 20:02:11 Gentleman_Qin 阅读数 7614

高光谱图像处理之目标检测技术

一、高光谱图像处理之目标检测


1、高光谱图像目标检测的发展趋势和研究现状:

   20世纪80年代末,美国的一些研究机构开始利用高光谱图像数据进行目标检测方面的研究。自上世纪九十年代,国外出现了进行高光谱图像目标检测算法理论研究的研究组。由Reed和Yu提出了基于广义似然比检验的恒虚警RX 检测器(RXD)。Chang课题组提出了基于正交子空间投影的OSP检测方法, Harsanyi提出了基于约束能量最小化的CEM算法。未来高光谱目标检测的发展将会越来越重视实用性,算法的性能将会进一步提高,同时更也加适合使用FPGA硬件对其进行加速从而具有更高的实际应用价值。

2、高光谱目标检测技术的应用范围:

   高光谱目标检测具有较强的实用性,可应用于公共安全、环境检测、城市规划、食品卫生、地质岩矿的识别等众多方面。


                         图1.1 高光谱图像数据结构

3、高光谱图像数据的特点:

   高光谱图像数据“图谱合一”,具有丰富的光谱维信息。高光谱图像数据共有三个维度,如图2.1所示,其中,图像空间维信息x、y用于表示物体的实际空间分布,而光谱波段L用于表示每个像素的光谱属性。

4、高光谱图像目标检测原理:

   高光谱图像的各波段在成像范围内都是连续成像,因此高光谱的光谱曲线一般是平滑的、连续的曲线。高光谱图像的波段L中涵盖了物质的光谱信息,而每种物质的光谱信息都不一样,我们可以利用图像像素的光谱波段L所包含的特定的光谱信息来判断该像素所代表的特定的物质种类。

5、高光谱图像目标检测流程:


                    图1.2 高光谱图像目标检测流程图

   如图所示,对于拍摄得到的原始高光谱图像数据,需要先对数据进行预处理,包括数据格式化、无用数据剔除以及亮度到反射率的转化等。同时,对于遥感仪拍摄的高光谱图像还需要进行辐射校正,在目标检测前,应对数据进行调整,包括数据归一化等。最后根据已知的先验信息选择相应的目标检测算法进行检测。

6、现场可编程门阵列(FPGA)在高光谱图像处理中的应用:

   一个FPGA可以大致定义为一系列互连的逻辑块。这些器件的主要优点之一是,为了实现不同的组合或时序逻辑功能,可以根据需要多次重新配置逻辑块及其互连。这一特性为FPGA提供了软件和硬件系统的优势。因为FPGA具有比专用集成电路(ASIC)更多的灵活性和更短的开发时间,更接近GPU提供的性能,但同时功耗要比GPU低得多。FPGA供应商通过改进FPGA体系结构(包括优化的硬件模块)并利用最新的硅技术不断提升FPGA的功耗和能效。可重构性、低功耗的特点以及FPGA对空间电离辐射耐受性的提高,这些因素已经使得FPGA成为目前板载高光谱遥感的最佳选择之一。


二、算法分类、比较和选择:


1、方法分类:

   高光谱目标检测方法按照先验信息是否已知分为监督方法和非监督方法。前者用于目标光谱已知的情况下,利用目标光谱与图像像元光谱进行匹配,从而完成目标检测,比如CEM算法、OSP算法;后者多用于异常目标检测,一般不需要目标和背景的先验信息,根据高光谱图像数据获取目标检测所需要的数据,然后根据数据的大小来判断是否为异常目标,比如RXD算法。

2、CEM、OSP、RXD算法的区别:

(1)CEM(Constrained Energy Minimization)算法:

   CEM算法主要思想是设计一个FIR线性滤波器,使得在满足约束条件式的情况下滤波器的输出能量最小。该算法不需要图像的背景信息,只需要知道要检测的先验光谱信息(目标向量)即可,具体方法是通过高光谱图像数据和先验已知的待检测目标确定一个滤波向量,让图像经过该滤波向量即可得到检测结果,其中滤波向量的作用是滤除图像中的非目标像素,让感兴趣的目标能够通过,同时抑制由其他信号带来的滤波器输出能量。

(2)OSP(Orthogonal Subspace Projection)算法:

   OSP算法与CEM算法相比,最大区别在于不仅需要目标的先验知识,还需要图像中背景的先验知识,但在实际中中这些先验信息很难全部得到。在高光谱检测中我们一般用其来检测异常。该算法需要前提条件:图像信息、目标像元、非目标像元(异常目标)信息。

(3)RXD(Reed-XiaoliDetector)算法:

   RXD算法是异常目标检测领域中最基础的算法,不需要目标光谱的先验知识,而是基于背景服从多元正态分布的假设,通过检测与背景分布中心相比属于异常像元,并在这些感兴趣区域进一步查找可能存在的目标。该算法主要针对的是小目标检测问题。

(4)确定所采用的目标检测算法:

   由于我们的应用场景多为有特定目标的目标检测,CEM正是针对未知场景中可能存在的特定目标的检测,只需要知道目标的光谱信息即可,而RXD算法适应于对特定场景的异常(未知目标)检测,而OSP算法除了需要已知目标光谱还需要背景信息。综上,我决定采用CEM算法进行高光谱目标检测的实现。


三、CEM算法分析:


1、算法步骤

(1)对高光谱图像进行预处理,得到二维化和归一化后的数据r(L*N);

(2)根据图像数据r,求得图像的自相关矩阵:

               

(3)确定目标光谱向量dd大小为L*1);

(4)根据公式:


                                   

   设计FIR线性滤波器:


(5)将归一化后的数据经过FIR滤波器,得到输出信号y

           

2、问题分解:

   CEM算法的实现可分为三部分:自相关矩阵、矩阵求逆、线性FIR滤波器。


图 1.3 CEM算法分解流程图

   如图所示,首先根据高光谱图像r求得自相关矩阵,再利用矩阵求逆模块求得自相关矩阵的逆矩阵,结合从光谱库获取到的目标向量的先验信息求得FIR滤波器的滤波向量,最后将高光谱图像r通过FIR滤波器即可得到最终的检测结果。


四、CEM算法实现:


1、算法流程:

   在MATLAB和C语言中实现CEM算法的具体流程如图所示,因为语言特性是串行执行命令,所以在编写程序时与硬件设计比较更加直接明了。

图1.4 CEM算法流程图

2、数据预处理:

   对前期得到的高光谱图像在MATLAB平台上进行预处理。这一过程主要对原始的200*200*189大小的高光谱图像进行操作:

(1)二维化:通过调用MATLAB里面的reshape()函数实现。

(2)归一化:采用“min-max”方法。 具体步骤是先找到数据的最大值
(maxA)和最小值(minA), 通过 y = (x-minA) /(maxA-minA) 计算的 y 即为归一化后的数据。高光谱数据量大,也造成了数据的存储比较困难,数据在程序中的存储等处理

3、CEM算法的MATLAB实现:

   首先,根据 2 对高光谱图像数据进行预处理,而后求其自相关矩阵。高光谱图像数据的大小为200*200*189,其中200*200为像素数,189为波段数。

              

   首先用reshape()函数和transpose()函数将200*200*189的三维高光谱图像数据转为189*40000的二维矩阵,再用自己写的Normalize()函数对矩阵数据用“min-max”方法进行归一化,然后根据公式式利用MATLAB中的矩阵求转置函数transpose()和矩阵相乘操作得到一个189*189的矩阵,最后对189*189的矩阵除以像素数N即可得到自相关矩阵。

最后,根据先验已知的目标向量和自相关矩阵R的逆矩阵(在MATLAB中矩阵R求逆即为(1/R))求得FIR滤波器,将高光谱图像模拟数据通过FIR滤波器,即可得到最终的检测结果。(本次测试中选取的目标向量 d 是模拟图像中的 C 物质)

4、CEM算法的C语言实现:

   在Visual Studio平台上完成CEM算法C程序的编写。相比于MATLAB实现,CEM算法的C语言实现主要难点在于矩阵运算。因为在C语言中,矩阵的转置、相乘、求逆等操作均没有现有的函数,需要编写相应的函数。在实现矩阵基本运算过程中,通过动态分配内存运用二维指针传递参数,完成矩阵加减法运算、矩阵转置运算、矩阵相乘运算以及矩阵求逆运算,这样可以节省存储空间,使用完后释放空间即可。

CEM算法的C语言实现主要包括如下步骤:

(1)在MATLAB中,将归一化后的高光谱图像数据转为189*40000的二维形式,保存为CEM.mat;

(2)编写矩阵初始化、矩阵转置、矩阵相乘、矩阵求逆、内存释放函数;

(3)编写main函数,读CEM.mat,调用上述函数,求得FIR滤波器,进而获得输出信号y,将其写入CEM.txt;

(4)在MATLAB中显示CEM.txt中数据所代表的图像。

5、难点解决:

(1)矩阵转置

   矩阵转置函数的输入是大小为m*n的矩阵A,输出是大小n*m为的矩阵B。采用嵌套的for循环分别遍历矩阵的行和列,将输入的二维矩阵A按列读出,重新按行写入新矩阵B中,即可实现矩阵的转置。

(2)矩阵相乘

   矩阵相乘函数的输入是大小m*n为的矩阵A和n*k的矩阵B,输出是大小为m*k的矩阵C。采用嵌套的for循环分别遍历矩阵的行和列,首先将矩阵A按行读出,矩阵B按列读出,然后将读出的矩阵A的第i行和矩阵B的第j列对应位相乘求和,将计算的结果写入矩阵C第i行第j列元素中。

(3)矩阵求逆——QR分解求逆

   QR分解求逆的原理是:对于可逆矩阵A,首先利用QR分解将A矩阵分解为Q矩阵和R矩阵。即A=QR,其中Q是正交矩阵,R是上三角矩阵。然后将公式左右同时求逆,可以求得A的逆矩阵,其中Q矩阵的逆矩阵和转置矩阵相同,R求逆有特定的公式。QR分解求逆的运算较为简单,且数据稳定度较高,可以得到误差较小的求逆结果。

6、算法实现结果和对比分析:

1)MATLAB和C语言实现CEM算法的检测结果如图所示:

       

      (a)               (b)            (c)

图1.6 原图CEM算法检测结果:(a)原图(每一行是一种物质)(b)MATLAB检测C物质(c)C语言检测C物质

 

通过对MATLAB和C语言实现结果进行对比,发现二者均成功实现了CEM算法并完成了对目标的检测,观察检测结果基本无差异。

######### 转载请注明出处:https://blog.csdn.net/Gentleman_Qin/article/details/79992314 #########


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);
	}
	
}

霍夫-圆形检测

彩色图像边缘检测

博文 来自: lpsl1882
没有更多推荐了,返回首页