[转载]距离变换算法

简介:

出处:http://blog.csdn.net/lichengyu/article/details/8009246

《图像处理分析与机器视觉》

 

计算全局图像中各个像素点对子图像的距离。

AL AL
AL P
AL  

 

                                  

Mask  1

 

  BR
P BR
BR BR

 

                       

Mask 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) 则为距离变换后的图像。

 

复制代码
#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;
}
复制代码

 





本文转自五岳博客园博客,原文链接:www.cnblogs.com/wuyuegb2312/articles/2810169.html,如需转载请自行联系原作者

目录
相关文章
|
7月前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
7月前
|
算法 计算机视觉
【MATLAB 】 EMD信号分解+希尔伯特黄变换+边际谱算法
【MATLAB 】 EMD信号分解+希尔伯特黄变换+边际谱算法
199 0
|
7月前
|
算法 计算机视觉
【MATLAB 】 EEMD 信号分解+希尔伯特黄变换+边际谱算法
【MATLAB 】 EEMD 信号分解+希尔伯特黄变换+边际谱算法
710 0
|
4月前
|
算法
基于小波变换的图像自适应增强算法
基于小波变换的图像自适应增强算法
19 0
|
6月前
|
机器学习/深度学习 算法
基于BP神经网络和小波变换特征提取的烟草香型分类算法matlab仿真,分为浓香型,清香型和中间香型
```markdown 探索烟草香型分类:使用Matlab2022a中的BP神经网络结合小波变换。小波分析揭示香气成分的局部特征,降低维度,PCA等用于特征选择。BP网络随后处理这些特征,以区分浓香、清香和中间香型。 ```
|
7月前
|
算法 数据安全/隐私保护 C++
基于二维CS-SCHT变换和扩频方法的彩色图像水印嵌入和提取算法matlab仿真
该内容是关于一个图像水印算法的描述。在MATLAB2022a中运行,算法包括水印的嵌入和提取。首先,RGB图像转换为YUV格式,然后水印通过特定规则嵌入到Y分量中,并经过Arnold置乱增强安全性。水印提取时,经过逆过程恢复,使用了二维CS-SCHT变换和噪声对比度(NC)计算来评估水印的鲁棒性。代码中展示了从RGB到YUV的转换、水印嵌入、JPEG压缩攻击模拟以及水印提取的步骤。
|
6月前
|
算法 计算机视觉
图像处理之基于采样距离变换算法
图像处理之基于采样距离变换算法
38 0
|
7月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于DCT变换和位平面分解的数字水印嵌入提取算法matlab仿真
这是一个关于数字水印算法的摘要:使用MATLAB2022a实现,结合DCT和位平面分解技术。算法先通过DCT变换将图像转至频域,随后利用位平面分解嵌入水印,确保在图像处理后仍能提取。核心程序包括水印嵌入和提取,以及性能分析部分,通过PSNR和NC指标评估水印在不同噪声条件下的鲁棒性。
|
7月前
|
算法 数据安全/隐私保护 计算机视觉
基于DCT变换的彩色图像双重水印嵌入和提取算法matlab仿真
**算法摘要:** - 图形展示:展示灰度与彩色图像水印应用,主辅水印嵌入。 - 软件环境:MATLAB 2022a。 - 算法原理:双重水印,转换至YCbCr/YIQ,仅影响亮度;图像分割为M×N块,DCT变换后嵌入水印。 - 流程概览:两步水印嵌入,每步对应不同图示表示。 - 核心代码未提供。
|
7月前
|
算法 计算机视觉
【MATLAB 】 CEEMDAN 信号分解+希尔伯特黄变换+边际谱算法
【MATLAB 】 CEEMDAN 信号分解+希尔伯特黄变换+边际谱算法
190 0