赞
踩
Distance Transforms of Sampled Functions
https://blog.csdn.net/frozenspring/article/details/78357858
https://blog.csdn.net/abcjennifer/article/details/7617883
https://blog.csdn.net/lingyunxianhe/article/details/73555520
https://blog.csdn.net/qq_34784753/article/details/68951918
1--浅析image,imagesc,imshow的用法
https://blog.csdn.net/zhupananhui/article/details/16340345
magesc: 在figure2中我们用imagesc来显示图像与figure1相比能较好的显示出来,同样我们也得搞明白调用imagesc时矩阵的数和colormap中索引的对应关系,与image不同的是imagesc采用的不是直接映射而是线性映射,至于什么是线性映射,我粗略的说一下,比如把区间A = [0,a]映射到区间B = [0,b]我们对A中的元素做A/a*b就可以了,矩阵的数到colormap索引的线性映射大概就是这样,Matlab会自动获取矩阵中数的最小值和最大值,并把区间[Cmin,Cmax]映射到colormap的[最小索引,最大索引]比如[1,64],然后再根据这个对应关系把图像显示出来,具体的算法细节是Matlab确定的,当然也可以自己指定显示范围,比如一副索引图像I范围为[27,218],而我只想显示[1 64 ],使用命令imagesc(I,[1 64])就可以了,如果你把上面程序中的imagesc(I)换成imagesc(I,[1,64]),那么figure2中的效果就和figure1中一样了,因为只是把[1,64]这个范围映射到色图,超过的都被认为是64。关于映射,我截图Matlab中imagesc的help页给大家看看,这里要自己慢慢体会哦,使用imagesc(I)这种线性映射就可以用到整个色图从而将图像较好的显示出来,这就是figure2中的显示效果比figure1中好的原因。
- A = [4 7 2 9 8;3 9 1 4 3;1 5 9 6 4;8 3 7 1 0]
- [i,j] = ind2sub(A,5)
- %3×3矩阵的第 5个元素的全下标;单下标转变为多下标
- ind=sub2ind(size(A),[1,2;3,4],[1,1;2,2])
- %矩阵第三行、第三列元素的序号
-
- A =
-
- 4 7 2 9 8
- 3 9 1 4 3
- 1 5 9 6 4
- 8 3 7 1 0
-
-
- i =
-
- 1
-
-
- j =
-
- 2
-
-
- ind =
-
- 1 2
- 7 8
- ind=sub2ind(siz,I,J):siz表示要转换的矩阵的行列数,I是要转换矩阵的行标,J是要转换矩阵的列标。I,J的行列数必须相同。
- 可以看出,在矩阵A中,下标(1,1)的索引值为1,下标(2,1)的索引值为2,下标(3,2)的索引值为7,下标(4,2)的索引值为8
2--matlab的double和single类型
代码部分
- % load image
- im = imread(fullfile(vl_root, 'data', 'roofs1.jpg')) ;
- im = im(100:200,100:200,:) ;
- imSize = [size(im,1) size(im,2)] ;
-
- % creates an edge map
- edges = zeros(imSize) + inf;
- edges(edge(rgb2gray(im), 'canny')) = 0 ;
-
- % compute distance transform
- [distanceTransform, neighbors] = vl_imdisttf(single(edges)) ;
-
- % plot
- [u,v] = meshgrid(1:imSize(2),1:imSize(1)) ;
- [v_,u_] = ind2sub(imSize, neighbors) ;
-
- % avoid cluttering the plot too much
- u = u(1:3:end,1:3:end) ;
- v = v(1:3:end,1:3:end) ;
- u_ = u_(1:3:end,1:3:end) ;
- v_ = v_(1:3:end,1:3:end) ;
-
- figure(1) ; clf ; imagesc(im) ; axis off image ;
- figure(2) ; clf ; imagesc(edges) ; axis off image ;
- figure(3) ; clf ; imshow(edges) ; axis off image ;
- hold on ; h = quiver(u,v,u_-u,v_-v,0) ; colormap gray ;
- figure(4) ; clf ; imagesc(sqrt(distanceTransform)) ; axis off image ;
vl_imdisttf函数:
输入为:二值图canny结果
输出为:[distanceTransform, neighbors]
其中neighbors的值表示每个像素点与图片中某个梯度点相邻,值是该点的位置
输入图像大小为101*101 (10201)
[v_,u_] = ind2sub(imSize, neighbors) ;
v_ 和 u_ 构成了neighbors对应的的坐标矩阵
比如104对用(2,3)----AC是怎么构成的看后面的解析
其中distanceTransform的值表示每个像素点与图片中相邻梯度点的距离值
定义:二值图像,任意点到最近背景点的距离,一般为非零点到最近零点的距离。
(1,1)最近的最近背景点是索引为:104
转换为下表为:(2,3)
(1,1)到(2,3)的距离为:5=(2-1)^2+(3-1)^2
- 在命令窗口输入:
- >> A=[4 7 2 9 8;3 9 1 4 3;1 5 9 6 4;8 3 7 1 0]
- A =
- 4 7 2 9 8
- 3 9 1 4 3
- 1 5 9 6 4
- 8 3 7 1 0
- 则A中每个元素对应的索引如下:
- 1 5 9 13 17
- 2 6 10 14 18
- 3 7 11 15 19
- 4 8 12 16 20
我们可以通过:AC=reshape(1:10201,101,101)
生成顺序矩阵,按列的方式存储索引(即matlab的方式)
或者按行生成顺序矩阵
AC=reshape(1:10201,101,101)
AB = AC’
[distanceTransform, neighbors] = vl_imdisttf(single(edges)) ;
- /** @internal
- ** @file vl_imdisttf.c
- ** @brief vl_imdisttf - MEX definition
- ** @author Andrea Vedaldi
- **/
-
- /*
- Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
- All rights reserved.
- This file is part of the VLFeat library and is made available under
- the terms of the BSD license (see the COPYING file).
- */
-
- #include <mexutils.h>
-
- #include <vl/generic.h>
- #include <vl/mathop.h>
- #include <vl/imopv.h>
-
- void
- mexFunction(int nout, mxArray *out[],
- int nin, const mxArray *in[])
- {
- vl_size M, N ;
- enum {IN_I = 0, IN_PARAM, IN_END} ;
- enum {OUT_DT = 0, OUT_INDEXES} ;
- vl_uindex * indexes = NULL ;
- mxClassID classId ;
- double const defaultParam [] = {1.0, 0.0, 1.0, 0.0} ;
- double const * param = defaultParam ;
-
- /* -----------------------------------------------------------------
- * Check the arguments
- * -------------------------------------------------------------- */
-
- if (nin < 1) {
- vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
- }
- if (nin > 2) {
- vlmxError(vlmxErrTooManyInputArguments, NULL) ;
- }
- if (nout > 2) {
- vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
- }
- classId = mxGetClassID(IN(I)) ;
- if (! vlmxIsMatrix(IN(I), -1, -1) ||
- (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS)) {
- vlmxError(vlmxErrInvalidArgument,
- "I is not a SINGLE or DOUBLE matrix.") ;
- }
- if (nin == 2) {
- if (! vlmxIsPlainVector(IN(PARAM), 4)) {
- vlmxError(vlmxErrInvalidArgument,
- "PARAM is not a 4-dimensional vector.") ;
- }
- param = mxGetPr (IN(PARAM)) ;
- if (param[0] < 0.0 ||
- param[2] < 0.0) {
- vlmxError(vlmxErrInvalidArgument,
- "Either PARAM[0] or PARAM[2] is negative.") ;
- }
- }
-
- M = mxGetM (IN(I)) ;
- N = mxGetN (IN(I)) ;
-
- OUT(DT) = mxCreateNumericMatrix (M, N, classId, mxREAL) ;
- if (nout > 1) {
- vl_uindex i ;
- OUT(INDEXES) = mxCreateDoubleMatrix (M, N, mxREAL) ;
- indexes = mxMalloc(sizeof(vl_uindex) * M * N) ;
- for (i = 0 ; i < M * N ; ++i) indexes[i] = i + 1 ;
- }
-
- /* -----------------------------------------------------------------
- * Do the job
- * -------------------------------------------------------------- */
-
- switch (classId) {
- case mxSINGLE_CLASS:
- vl_image_distance_transform_f((float const*)mxGetData(IN(I)),
- M, N,
- 1, M,
- (float*)mxGetPr(OUT(DT)),
- indexes,
- param[2],
- param[3]) ;
-
- vl_image_distance_transform_f((float*)mxGetPr(OUT(DT)),
- N, M,
- M, 1,
- (float*)mxGetPr(OUT(DT)),
- indexes,
- param[0],
- param[1]) ;
- break ;
-
- case mxDOUBLE_CLASS:
- vl_image_distance_transform_d((double const*)mxGetData(IN(I)),
- M, N,
- 1, M,
- (double*)mxGetPr(OUT(DT)),
- indexes,
- param[2],
- param[3]) ;
-
- vl_image_distance_transform_d((double*)mxGetPr(OUT(DT)),
- N, M,
- M, 1,
- (double*)mxGetPr(OUT(DT)),
- indexes,
- param[0],
- param[1]) ;
- break;
-
- default:
- abort() ;
- }
-
- if (indexes) {
- vl_uindex i ;
- double * pt = mxGetPr(OUT(INDEXES)) ;
- for (i = 0 ; i < M * N ; ++i) pt[i] = indexes[i] ;
- mxFree(indexes) ;
- }
- }
- VL_EXPORT void
- vl_image_distance_transform_f (float const * image,
- vl_size numColumns,
- vl_size numRows,
- vl_size columnStride,
- vl_size rowStride,
- float * distanceTransform,
- vl_uindex * indexes,
- float coeff,
- float offset) ;
- VL_EXPORT void
- VL_XCAT(vl_image_distance_transform_,SFX)
- (T const * image,
- vl_size numColumns,
- vl_size numRows,
- vl_size columnStride,
- vl_size rowStride,
- T * distanceTransform,
- vl_uindex * indexes,
- T coeff,
- T offset)
- {
- /* Each image pixel corresponds to a parabola. The algorithm scans
- such parabolas from left to right, keeping track of which
- parabolas belong to the lower envelope and in which interval. There are
- NUM active parabolas, FROM stores the beginning of the interval
- for which a certain parabola is part of the envoelope, and WHICH store
- the index of the parabola (that is, the pixel x from which the parabola
- originated).
- 每个图像像素对应一个抛物线。算法扫描这样的抛物线从左到右,
- 跟踪哪个抛物线属于下包层和哪个区间。 有NUM个有效抛物线,
- FROM存储某个抛物线是envoelope的一部分的间隔的开始,
- WHICH存储抛物线的指数(即抛物线起源的像素x)。
- */
- vl_uindex x, y ;
- T * from = vl_malloc (sizeof(T) * (numColumns + 1)) ;
- T * base = vl_malloc (sizeof(T) * numColumns) ;
- vl_uindex * baseIndexes = vl_malloc (sizeof(vl_uindex) * numColumns) ;
- vl_uindex * which = vl_malloc (sizeof(vl_uindex) * numColumns) ;
- vl_uindex num = 0 ;
-
- for (y = 0 ; y < numRows ; ++y) {
- num = 0 ;
- for (x = 0 ; x < numColumns ; ++x) {
- T r = image[x * columnStride + y * rowStride] ;
- T x2 = x * x ;
- #if (FLT == VL_TYPE_FLOAT)
- T from_ = - VL_INFINITY_F ;
- #else
- T from_ = - VL_INFINITY_D ;
- #endif
-
- /*
- Add next parabola (there are NUM so far). The algorithm finds
- intersection INTERS with the previously added parabola. If
- the intersection is on the right of the "starting point" of
- this parabola, then the previous parabola is kept, and the
- new one is added to its right. Otherwise the new parabola
- "eats" the old one, which gets deleted and the check is
- repeated with the parabola added before the deleted one.
- 添加下一个抛物线(到目前为止有NUM个)。 算法找到交叉口INTERS与先前添加的抛物线。
- 如果交叉点位于“起点”的右侧这个抛物线,然后保持先前的抛物线,并且右边添加了新的。
- 否则新的抛物线“吃掉”旧的,将被删除,并在删除之前添加抛物线重复检查。
- */
-
- while (num >= 1) {
- vl_uindex x_ = which[num - 1] ;
- T x2_ = x_ * x_ ;
- T r_ = image[x_ * columnStride + y * rowStride] ;
- T inters ;
- if (r == r_) {
- /* handles the case r = r_ = \pm inf */
- inters = (x + x_) / 2.0 + offset ;
- }
- #if (FLT == VL_TYPE_FLOAT)
- else if (coeff > VL_EPSILON_F)
- #else
- else if (coeff > VL_EPSILON_D)
- #endif
- {
- inters = ((r - r_) + coeff * (x2 - x2_)) / (x - x_) / (2*coeff) + offset ;
- } else {
- /* If coeff is very small, the parabolas are flat (= lines).
- In this case the previous parabola should be deleted if the current
- pixel has lower score
- 如果coeff非常小,抛物线是平的(=线)。 在这种情况下,如果当前像素的得分较低,则应删除
- 先前的抛物线
- */
- #if (FLT == VL_TYPE_FLOAT)
- inters = (r < r_) ? - VL_INFINITY_F : VL_INFINITY_F ;
- #else
- inters = (r < r_) ? - VL_INFINITY_D : VL_INFINITY_D ;
- #endif
- }
- if (inters <= from [num - 1]) {
- /* delete a previous parabola */
- -- num ;
- } else {
- /* accept intersection */
- from_ = inters ;
- break ;
- }
- }
-
- /* add a new parabola */
- which[num] = x ;
- from[num] = from_ ;
- base[num] = r ;
- if (indexes) baseIndexes[num] = indexes[x * columnStride + y * rowStride] ;
- num ++ ;
- } /* next column */
-
- #if (FLT == VL_TYPE_FLOAT)
- from[num] = VL_INFINITY_F ;
- #else
- from[num] = VL_INFINITY_D ;
- #endif
-
- /* fill in */
- num = 0 ;
- for (x = 0 ; x < numColumns ; ++x) {
- double delta ;
- while (x >= from[num + 1]) ++ num ;
- delta = (double) x - (double) which[num] - offset ;
- distanceTransform[x * columnStride + y * rowStride]
- = base[num] + coeff * delta * delta ;
- if (indexes) {
- indexes[x * columnStride + y * rowStride]
- = baseIndexes[num] ;
- }
- }
- } /* next row */
-
- vl_free (from) ;
- vl_free (which) ;
- vl_free (base) ;
- vl_free (baseIndexes) ;
- }
- /** @internal @brief IEEE single precision infinity constant */
- static union { vl_uint32 raw ; float value ; }
- const vl_infinity_f =
- { 0x7F800000UL } ;
-
- /** @internal @brief IEEE double precision infinity constant */
- static union { vl_uint64 raw ; double value ; }
- const vl_infinity_d =
- #ifdef VL_COMPILER_MSC
- { 0x7FF0000000000000ui64 } ;
- #else
- { 0x7FF0000000000000ULL } ;
- #endif
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。