距离变换
来源:互联网 发布:乔丹生涯场均数据 编辑:程序博客网 时间:2024/05/20 16:01
出处:桑卡, 《图像处理分析与机器视觉》
计算全局图像中各个像素点对子图像的距离。
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 matricesCV_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 rightfor( 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 leftfor( 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 matricesCV_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 boundaryfor( 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;}
原图 棋盘距离变换
城市距离变换 欧式距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换
- 距离变换(cvDistTransform)
- 距离变换的理解
- Emgu 距离变换
- [DLX] [NOIP2009] 靶形数独
- Java——集合IO综合应用
- PLSQL实现分页
- 第十一章 泛型算法
- 微软9月22日笔试题
- 距离变换
- 射极跟随器特点
- 时间控件和在线编辑器
- 算法之美——开门人和关门人(printf,scanf用法)
- 陈雄华 精通Spring 2.x——企业应用开发详解
- 运行现有网站的同时,配置FMS使用80端口代理rtmpt协议播放流媒体
- Curling 2.0 poj DFS
- poj3628 Bookshelf 2(0/背包)
- 使用PowerBuilder 9编绎DLL类型,有点问题.处理过程记录如下."Error opening file 'c:\windows\system32\cgen\en32t.h'"