距离变换 matlab实现 opencv实现
来源:互联网 发布:足球数据库软件哪个好 编辑:程序博客网 时间:2024/05/17 13:46
距离变换将一幅二值图像(特征点为0,非特征点为1)变换为一幅灰度图像,灰度图像每一点的像素值为二值图像上非零像素到最近的0像素的距离。
Syntax
D = bwdist(BW)
[D,IDX] = bwdist(BW)
[D,IDX] = bwdist(BW,method)
Description
D = bwdist(BW) computesthe Euclidean distance transform of the binary imageBW.For each pixel inBW, the distance transform assignsa number that is the distance between that pixel and the nearest nonzeropixel ofBW.bwdist uses theEuclidean distance metric by default. BW can haveany dimension.D is the same size asBW.
[D,IDX] = bwdist(BW) alsocomputes the closest-pixel map in the form of an index array,IDX.(The closest-pixel map is also called the feature map, feature transform,or nearest-neighbor transform.)IDX has the samesize as BW and D. Each elementofIDX contains the linear index of the nearestnonzero pixel ofBW.
[D,IDX] = bwdist(BW,method) computesthe distance transform, wheremethod specifiesan alternate distance metric.method cantake any of the following values. Themethod stringcan be abbreviated.
Method
Description
'chessboard'
In2-D, the chessboard distance between (x1,y1) and (x2,y2)is max(│x1 –x2│,│y1 –y2│).
'cityblock'
In2-D, the cityblock distance between (x1,y1) and (x2,y2)is │x1 –x2│+ │y1 –y2│.
'euclidean'
In2-D, the Euclidean distance between (x1,y1) and (x2,y2)is
This is the default method.
'quasi-euclidean'
In2-D, the quasi-Euclidean distance between (x1,y1)and (x2,y2) is
Class Support
BW can be numeric or logical, and it mustbe nonsparse. D is a single matrix with the samesize asBW. The class ofIDX dependson the number of elements in the input image, and is determined usingthe following table.
Examples
Compute the Euclidean distance transform.
bw = zeros(5,5); bw(2,2) = 1; bw(4,4) = 1bw = 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0[D,IDX] = bwdist(bw)D = 1.4142 1.0000 1.4142 2.2361 3.1623 1.0000 0 1.0000 2.0000 2.2361 1.4142 1.0000 1.4142 1.0000 1.4142 2.2361 2.0000 1.0000 0 1.0000 3.1623 2.2361 1.4142 1.0000 1.4142IDX = 7 7 7 7 7 7 7 7 7 19 7 7 7 19 19 7 7 19 19 19 7 19 19 19 19
In the nearest-neighbor matrix IDX the values 7 and 19 representthe position of the nonzero elements using linear matrix indexing.If a pixel contains a 7, its closest nonzero neighbor is at linearposition 7.
Compare the 2-D distance transforms for each of the supporteddistance methods. In the figure, note how the quasi-Euclidean distancetransform best approximates the circular shape achieved by the Euclideandistance method.
bw = zeros(200,200); bw(50,50) = 1; bw(50,150) = 1;bw(150,100) = 1;D1 = bwdist(bw,'euclidean');D2 = bwdist(bw,'cityblock');D3 = bwdist(bw,'chessboard');D4 = bwdist(bw,'quasi-euclidean');figuresubplot(2,2,1), subimage(mat2gray(D1)), title('Euclidean')hold on, imcontour(D1)subplot(2,2,2), subimage(mat2gray(D2)), title('City block')hold on, imcontour(D2)subplot(2,2,3), subimage(mat2gray(D3)), title('Chessboard')hold on, imcontour(D3)subplot(2,2,4), subimage(mat2gray(D4)), title('Quasi-Euclidean')hold on, imcontour(D4)
Compare isosurface plots for the distance transforms of a 3-Dimage containing a single nonzero pixel in the center.
bw = zeros(50,50,50); bw(25,25,25) = 1;D1 = bwdist(bw);D2 = bwdist(bw,'cityblock');D3 = bwdist(bw,'chessboard');D4 = bwdist(bw,'quasi-euclidean');figuresubplot(2,2,1), isosurface(D1,15), axis equal, view(3)camlight, lighting gouraud, title('Euclidean')subplot(2,2,2), isosurface(D2,15), axis equal, view(3)camlight, lighting gouraud, title('City block')subplot(2,2,3), isosurface(D3,15), axis equal, view(3)camlight, lighting gouraud, title('Chessboard')subplot(2,2,4), isosurface(D4,15), axis equal, view(3)camlight, lighting gouraud, title('Quasi-Euclidean')
出处:桑卡, 《图像处理分析与机器视觉》
计算全局图像中各个像素点对子图像的距离。
ALALALPALMask 1
BRPBRBRBRMask 2
1. 将图像进行二值化,子图像值为0,背景为255;
2. 利用Mask 1从左向右,从上到下扫描,p点是当前像素点,q点是Mask 1中AL邻域中的点,D()为距离计算,包括棋盘距离、城市距离和欧式距离。F(p)为p点的像素值,计算
F(p) = min( F(p), F(q)+D(p,q) ), 其中,q属于AL.
3. 再利用Mask 2从右向左,从下向上扫描,计算
F(p) = min( F(p), F(q)+D(p,q) ), 其中,q属于BR
4. F(p) 则为距离变换后的图像。
代码如下,基于OpenCV 2.4
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include "math.h"
- #include <stdio.h>
- using namespace cv;
- Mat& DistTran(Mat& I);
- Mat& NormImage(Mat& I);
- static float Round(float f)
- {
- return ( ceil(f)-f > f-floor(f) ) ? floor(f) : ceil(f);
- }
- int ChessBoardDist(int x1, int y1, int x2, int y2)
- {
- return (abs(x1-x2) > abs(y1-y2)) ? abs(x1-x2) : abs(y1-y2);
- }
- int CityBlockDist(int x1, int y1, int x2, int y2)
- {
- return ( abs(x1-x2) + abs(y1-y2) );
- }
- float EuclideanDist(int x1, int y1, int x2, int y2)
- {
- return sqrt( (float)((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)) );
- }
- int MyMin(int x, int y)
- {
- return (x < y) ? x : y;
- }
- float MyMin(float x, float y)
- {
- return (x < y) ? x : y;
- }
- /**
- * @function main
- */
- int main( int argc, char** argv )
- {
- char* imageName = "test_wushuang.bmp";
- Mat image;
- image = imread(imageName,1);
- if(!image.data)
- {
- printf("No image data\n");
- }
- Mat gray_image;
- cvtColor( image, gray_image, CV_RGB2GRAY );
- DistTran( gray_image );
- NormImage( gray_image );
- imwrite("EuclideanDist_wushuang.bmp", gray_image);
- namedWindow( imageName, CV_WINDOW_AUTOSIZE );
- namedWindow( "Gray image", CV_WINDOW_AUTOSIZE );
- imshow( imageName, image );
- imshow( "Gray image", gray_image );
- waitKey(0);
- return 0;
- }
- Mat& DistTran(Mat& I)
- {
- // accept only char type matrices
- CV_Assert(I.depth() != sizeof(uchar));
- int channels = I.channels();
- int nRows = I.rows * channels;
- int nCols = I.cols;
- //if (I.isContinuous())
- //{
- // nCols *= nRows;
- // nRows = 1;
- //}
- int i,j;
- uchar* p;
- uchar* q;
- //int min = 0;
- //int dis = 0;
- float fMin = 0.0;
- float fDis = 0.0;
- // pass throuth from top to bottom, left to right
- for( i = 1; i < nRows-1; ++i)
- {
- p = I.ptr<uchar>(i);
- for ( j = 1; j < nCols; ++j)
- {
- /*q = I.ptr<uchar>(i-1);
- dis = CityBlockDist(i, j, i-1, j-1);
- min = MyMin( p[j], dis+q[j-1] );
- dis = CityBlockDist(i, j, i-1, j);
- min = MyMin( min, dis+q[j] );
- q = I.ptr<uchar>(i);
- dis = CityBlockDist(i, j, i, j-1);
- min = MyMin( min, dis+q[j-1] );
- q = I.ptr<uchar>(i+1);
- dis = CityBlockDist(i, j, i+1, j-1);
- min = MyMin( min, dis+q[j-1] );
- p[j] = min;*/
- q = I.ptr<uchar>(i-1);
- fDis = EuclideanDist(i, j, i-1, j-1);
- fMin = MyMin( (float)p[j], fDis+q[j-1] );
- fDis = EuclideanDist(i, j, i-1, j);
- fMin = MyMin( fMin, fDis+q[j] );
- q = I.ptr<uchar>(i);
- fDis = EuclideanDist(i, j, i, j-1);
- fMin = MyMin( fMin, fDis+q[j-1] );
- q = I.ptr<uchar>(i+1);
- fDis = EuclideanDist(i, j, i+1, j-1);
- fMin = MyMin( fMin, fDis+q[j-1] );
- p[j] = (uchar)Round(fMin);
- }
- }
- // pass throuth from bottom to top, right to left
- for( i = nRows-2; i > 0; i-- )
- {
- p = I.ptr<uchar>(i);
- for( j = nCols-1; j >= 0; j-- )
- {
- /*q = I.ptr<uchar>(i+1);
- dis = CityBlockDist(i, j, i+1, j);
- min = MyMin( p[j], dis+q[j] );
- dis = CityBlockDist(i, j, i+1, j+1);
- min = MyMin( min, dis+q[j+1] );
- q = I.ptr<uchar>(i);
- dis = CityBlockDist(i, j, i, j+1);
- min = MyMin( min, dis+q[j+1] );
- q = I.ptr<uchar>(i-1);
- dis = CityBlockDist(i, j, i-1, j+1);
- min = MyMin( min, dis+q[j+1] );
- p[j] = min;*/
- q = I.ptr<uchar>(i+1);
- fDis = EuclideanDist(i, j, i+1, j);
- fMin = MyMin( (float)p[j], fDis+q[j] );
- fDis = EuclideanDist(i, j, i+1, j+1);
- fMin = MyMin( fMin, fDis+q[j+1] );
- q = I.ptr<uchar>(i);
- fDis = EuclideanDist(i, j, i, j+1);
- fMin = MyMin( fMin, fDis+q[j+1] );
- q = I.ptr<uchar>(i-1);
- fDis = EuclideanDist(i, j, i-1, j+1);
- fMin = MyMin( fMin, fDis+q[j+1] );
- p[j] = (uchar)Round(fMin);
- }
- }
- return I;
- }
- Mat& NormImage(Mat& I)
- {
- // accept only char type matrices
- CV_Assert(I.depth() != sizeof(uchar));
- int channels = I.channels();
- int nRows = I.rows * channels;
- int nCols = I.cols;
- //if (I.isContinuous())
- //{
- // nCols *= nRows;
- // nRows = 1;
- //}
- int i,j;
- uchar* p;
- int min = 256;
- int max = -1;
- // Do not count the outer boundary
- for( i = 1; i < nRows-1; ++i)
- {
- p = I.ptr<uchar>(i);
- for ( j = 1; j < nCols-1; ++j)
- {
- if( min > p[j] ) min = p[j];
- if( max < p[j] ) max = p[j];
- }
- }
- for( i = 1; i < nRows-1; ++i)
- {
- p = I.ptr<uchar>(i);
- for ( j = 1; j < nCols-1; ++j)
- {
- p[j] = (p[j] - min) * 255 / (max - min);
- }
- }
- return I;
- }
原图 棋盘距离变换
城市距离变换 欧式距离变换
- 距离变换 matlab实现 opencv实现
- Matlab实现FFT变换
- Matlab实现FFT变换
- MATLAB 实现Hough变换
- Matlab 距离变换
- opencv 距离变换
- opencv距离变换
- 图像识别中距离变换的原理及作用详解,并附用OpenCV中的distanceTransform实现距离变换的代码!
- matlab实现信号的变换
- DCT变换及matlab实现
- matlab实现信号的变换
- matlab实现图像DCT变换
- OpenCV实现仿射变换
- Gabor变换的opencv实现
- OpenCV实现仿射变换
- OpenCV实现基本灰度变换
- 距离变换代码实现(c代码)
- OpenCV实现fft2、ifft2变换和matlab中psf2otf()函数的功能
- 物化视图rowid
- 二分排序法
- js中的类,对象和继承
- 我的码农辛路历程
- 一诺千钧
- 距离变换 matlab实现 opencv实现
- aspxgrdview 编辑
- Adblock Plus过滤规则
- sql语句中select top n与oracle的rownum与mysql的limit用法
- jquery拖动效果
- C#控制鼠标动作
- Java实现id自增的字符串类型的数字编号
- ios 16进制数转换为10进制数
- php json arr obj 简单记录