史蒂夫与MATLAB图像处理

图像处理的概念、算法和MATLAB

一个像素的形状是什么?

内容

一个像素的形状

一个像素的形状是什么?在不同时期,我有一个像素作为一个广场(经常),一个点(有时),或一个矩形(偶尔)。我记得在研究生院做一些作业,我们将像素作为六边形。

我以前工作在之前写的几篇计算Feret直径,不过,我开始接受可能的实用性考虑像素的圆。(见29 - 9 - 2017,10月24日—- 2017,2月20 - - 2018)。让我试着解释为什么。

这是一个二进制图像前景与单个blob(或“对象”或“连接组件。”)

bw = imread (“玛莎的葡萄园(30 x20) . png”);imshow (bw)

大多数时候,我们认为图像的像素作为广场与单位面积。

pixelgrid

我们可以使用找到把x和y坐标美元美元的像素中心,然后我们可以使用convhull找到他们的凸包。我认为,作为一种优化往往会减少执行时间和内存,我要预处理输入二进制图像通过调用bwperim。我不会显示步骤都在这个例子中,虽然。

(y、x) =找到(bwperim (bw));持有情节(x, y,“。”)举行标题(“像素中心”)h = convhull (x, y);x_hull = x (h);y_hull = y (h);持有hull_line =情节(x_hull y_hull,的r *,“MarkerSize”12);持有标题(“像素中心和凸包顶点”)

注意,有一些链三个或三个以上共线的凸壳顶点。

xlim ([21.5 - 32.5]) ylim([9.5 - 15.5])标题(“共线的凸壳顶点的)

在其他的一些相关的处理步骤Feret直径测量,共线的凸壳顶点会导致一些问题。我们可以消除这些顶点直接调用convhull使用“简化”参数。

h = convhull (x, y,“简化”,真正的);x_hull = x (h);y_hull = y (h);删除(hull_line);持有情节(x_hull y_hull,的r *,“MarkerSize”,12)标题(“共线的船体顶点删除”)
imshow (bw)情节(x_hull y_hull,的r - *,“线宽”2,“MarkerSize”,12)标题(”一个Blob年代凸包和它的顶点)

注意,有白色显示红色凸包外多边形。因为我们只使用像素中心

使用像素中心的弱点

考虑一个简单的二进制对象,一个只有一行。

bw2 = false (15);bw2 (3, 5:10) = true;imshow (bw2) pixelgrid [y、x] =找到(bw2);

这个函数convhull甚至不共线的点。

试一试船体= convhull (x, y,“简化”,真正的);e流(从convhull错误消息:“% s”\ n”,e.message);结束
从convhull错误消息:“错误计算凸壳。点可能是共线的。”

但即使它并返回一个答案,答案将会是一个堕落的多边形长度5(尽管前景像素的数量是6)和零区。

持有情节(x, y,的r - *,“MarkerSize”12“线宽”,2)标题(退化多边形凸包的)

我们可以解决这个问题用简并问题方形像素

方形像素

在上面的凸壳的计算,我们每个像素作为一个治疗。相反,我们可以把每个像素作为广场通过计算所有的凸包角落每一个像素。这是一个方法来执行计算。

偏移量= (0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 0.5];偏移量=重塑(偏移量,1、2、[]);P = (x, y);Q = P +偏移量;R =排列(Q, [1 3 2]);S =重塑(R, [], 2);h = convhull(年代,“简化”,真正的);x_hull = S (h, 1);y_hull = S (h, 2);
imshow bw2 pixelgrid持有情节(x_hull y_hull,的r - *,“MarkerSize”12“线宽”,2)标题(方形像素的凸包)

乍一看这个结果看起来不错。然而,它就失去了它的一些吸引力当你考虑计算最大Feret直径的影响。

点= [x_hull y_hull];[d, end_points] = maxFeretDiameter(点,antipodalPairs(点))情节(end_points (: 1) end_points (:, 2),“k”,“线宽”,3)标题(最大Feret直径不是水平的)
d = 6.0828 end_points = 10.5000 2.5000 4.5000 3.5000

这个水平段的最大Feret距离是6.0828美元\√{37}$),而不是6度和相应的定位是:

atan2d (1,6)
ans = 9.4623

而不是0。

是使用另一个有价值的尝试钻石像素。

钻石像素

而不是使用每个像素的四个角落,让我们试着用每个像素边缘的中间。一旦我们定义补偿,代码是方形像素一模一样。

偏移量= (0.5 0.0 0.0 0.5 -0.5 0.0 0.0 -0.5];偏移量=重塑(偏移量,1、2、[]);P = (x, y);Q = P +偏移量;R =排列(Q, [1 3 2]);S =重塑(R, [], 2);h = convhull(年代,“简化”,真正的);x_hull = S (h, 1);y_hull = S (h, 2);
imshow bw2 pixelgrid持有情节(x_hull y_hull,的r - *,“MarkerSize”12“线宽”,2)标题(“钻石像素的凸包”)

现在马克斯Feret直径结果看起来更好的水平行像素。

点= [x_hull y_hull];[d, end_points] = maxFeretDiameter(点,antipodalPairs(点))情节(end_points (: 1) end_points (:, 2),“k”,“线宽”,3)
d = 6 end_points = 10.5000 3.0000 4.5000 3.0000

不过,等等。考虑一个平方blob。

bw3 = false (9, 9);bw3 (3:7, 3:7) = true;imshow (bw3) pixelgrid [y、x] =找到(bw3);P = (x, y);Q = P +偏移量;R =排列(Q, [1 3 2]);S =重塑(R, [], 2);h = convhull(年代,“简化”,真正的);x_hull = S (h, 1);y_hull = S (h, 2);
持有情节(x_hull y_hull,的r - *,“MarkerSize”12“线宽”2)点= [x_hull y_hull];[d, end_points] = maxFeretDiameter(点,antipodalPairs(点))情节(end_points (: 1), end_points (:, 2),“k”,“线宽”,3)标题(“马克斯Feret直径不是在45度的)
d = 6.4031 end_points = 7.5000 3.0000 2.5000 7.0000

我们希望看到马克斯Feret面向直径45度,显然我们没有。

圆形像素

好吧,我要做一个尝试。我要把每一个像素一个。我要近似圆使用24分,沿圆周间隔每隔15度。

thetad = 0:15:345;偏移量= 0.5 * (cosd (thetad);信德(thetad)];偏移量=重塑(偏移量,1、2、[]);Q = P +偏移量;R =排列(Q, [1 3 2]);S =重塑(R, [], 2);h = convhull(年代,“简化”,真正的);x_hull = S (h, 1);y_hull = S (h, 2);imshow bw3 pixelgrid持有情节(x_hull y_hull,的r - *,“MarkerSize”12“线宽”2)点= [x_hull y_hull];[d, end_points] = maxFeretDiameter(点,antipodalPairs(点))情节(end_points (: 1), end_points (:, 2),“k”,“线宽”3)轴持有
d = 6.6569 end_points = 7.3536 7.3536 2.6464 2.6464

现在马克斯Feret直径方向就是我们当然希望,这是美元\点45 ^{\保监会}$。的取向也会像预期的水平或垂直的像素。

不过,一个圆形的近似不可能总是给用户可能期望什么。让我们回到我开始的玛莎Vinyard blob。我写了一个函数调用pixelHull可以计算凸壳的二进制图像像素以各种不同的方式。调用pixelHull (bw, 24)使用24分圆近似计算像素的船体。

这是使用近似最大Feret直径。

imshow (bw) V = pixelHull (bw, 24);持有情节(V (: 1), V (:, 2),的r -,“线宽”2,“MarkerSize”12)(d, end_points) = maxFeretDiameter (V, antipodalPairs (V));情节(end_points (: 1) end_points (:, 2),“米”,“线宽”3)轴pixelgrid举行

我想很多人可能期望的最大Feret直径细致在这种情况下,但这并不完全做到这一点。

xlim ([22.07 - 31.92]) ylim ([8.63 - 15.20])

你必须使用方形像素细致。

imshow (bw) V = pixelHull (bw,“广场”);持有情节(V (: 1), V (:, 2),的r -,“线宽”2,“MarkerSize”12)(d, end_points) = maxFeretDiameter (V, antipodalPairs (V));情节(end_points (: 1) end_points (:, 2),“米”,“线宽”3)轴pixelgrid举行
xlim ([22.07 - 31.92]) ylim ([8.63 - 15.20])

这一切后,我仍然不完全确定这形状的假设通常效果最好。我唯一的公司的结论是,点近似是最糟糕的选择。相关的简并点像素太麻烦了。

如果你有意见,请在评论中分享。(注:评论说:“史蒂夫,你完全对这事太多心了”是完全合法的。)

其余的文章包含上面的代码所使用的功能。

函数V = pixelHull (P,类型)如果输入参数个数< 2类型= 24;结束如果islogical (P) P = bwperim (P);(i, j) =找到(P);P = [j];结束如果比较字符串(类型,“广场”)偏移量= (0.5 -0.5 0.5 0.5 -0.5 - 0.5 -0.5 - -0.5);elseif比较字符串(类型,“钻石”)偏移量= (0.5 0 0 0.5 - -0.5 0 0 -0.5];其他的%类型是多个角度采样一个圆的直径1。thetad = linspace(0360 + 1)型”;thetad(结束)= [];偏移量= 0.5 * (cosd (thetad)信德(thetad)];结束偏移量=补偿”;偏移量=重塑(偏移量,1、2、[]);Q = P +偏移量;R =排列(Q, [1 3 2]);S =重塑(R, [], 2);k = convhull(年代,“简化”,真正的);V = S (k,:);结束




发表与MATLAB®R2017b

|
  • 打印

评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。