步骤:
1)从左到右,从上到下扫描
2)从右到左,从下到上扫描
#include <opencv2/highgui.hpp>
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <fstream>
using namespace std;
#ifndef uint8
#define uint8 unsigned char
#endif
/*left mask *************************
*|AL|AL|
*|AL|P |
*|AL|
*
****************************/
void leftTop_mask_move(cv::Mat &src, cv::Mat &distance)
{
//firt line
{
uint8 *pcur = distance.ptr<uint8>(0);
uint8 *pafter = distance.ptr<uint8>(1);
for(int j = 1; j < distance.cols; j++)
{
uint8 *pmin = pcur+j;
if((*(pcur+j -1)+1) < *pmin)
{
*pmin = *(pcur+j-1)+1;
}
if((*(pafter+j -1)+2) < *pmin)
{
*pmin = *(pafter+j-1)+2;
}
}
}
for(int i = 2; i < distance.rows; i++)
{
uint8 *pprev = distance.ptr<uint8>(i-2);
uint8 *pcur = distance.ptr<uint8>(i-1);
uint8 *pafter = distance.ptr<uint8>(i);
for(int j = 0; j < distance.cols; j++)
{
uint8 *pmin = pcur+j;
if(j == 0)
{
if((*(pprev+j)+1) < *pmin)
{
*pmin = *(pprev+j)+1;
}
}
else
{
if((*(pprev+j-1) + 2) < *pmin)
{
*pmin = *(pprev+j-1) + 2;
}
if((*(pprev+j)+1) < *pmin)
{
*pmin = *(pprev+j)+1;
}
if((*(pcur+j -1)+1) < *pmin)
{
*pmin = *(pcur+j-1)+1;
}
if((*(pafter+j -1)+2) < *pmin)
{
*pmin = *(pafter+j-1)+2;
}
}
}
}
//last line
{
uint8 *pcur = distance.ptr<uint8>(distance.rows-1);
uint8 *pprev= distance.ptr<uint8>(distance.rows-2);
for(int j = 1; j < distance.cols; j++)
{
uint8 *pmin = pcur+j;
if((*(pprev+j-1) + 2) < *pmin)
{
*pmin = *(pprev+j-1) + 2;
}
if((*(pprev+j)+1) < *pmin)
{
*pmin = *(pprev+j)+1;
}
if((*(pcur+j -1)+1) < *pmin)
{
*pmin = *(pcur+j-1)+1;
}
}
}
return;
}
/*right mask *************************
* |BR|
*|P |BR|
*|BR|BR|
*
****************************/
void rightTop_mask_move(cv::Mat &src, cv::Mat &distance)
{
//last line
{
uint8 *pcur = distance.ptr<uint8>(distance.rows-1);
uint8 *pprev= distance.ptr<uint8>(distance.rows-2);
for(int j = 0; j < distance.cols-1; j++)
{
uint8 *pmin = pcur+j;
if((*(pprev+j+1) + 2) < *pmin)
{
*pmin = *(pprev+j+1) + 2;
}
if((*(pcur+j + 1)+1) < *pmin)
{
*pmin = *(pcur+j+1)+1;
}
}
}
for(int i = distance.rows - 1 ; i > 1; i--)
{
uint8 *pprev = distance.ptr<uint8>(i-2);
uint8 *pcur = distance.ptr<uint8>(i-1);
uint8 *pafter = distance.ptr<uint8>(i);
for(int j = 0; j < distance.cols; j++)
{
uint8 *pmin = pcur+j;
if(j == (distance.cols-1))
{
if((*(pafter+j)+1) < *pmin)
{
*pmin = *(pafter+j)+1;
}
}
else
{
if((*(pafter+j+1) + 2) < *pmin)
{
*pmin = *(pafter+j-1) + 2;
}
if((*(pafter+j)+1) < *pmin)
{
*pmin = *(pafter+j)+1;
}
if((*(pcur+j+1)+1) < *pmin)
{
*pmin = *(pcur+j+1)+1;
}
if((*(pprev+j+1)+2) < *pmin)
{
*pmin = *(pprev+j+1)+2;
}
}
}
}
//firt line
{
uint8 *pcur = distance.ptr<uint8>(0);
uint8 *pafter = distance.ptr<uint8>(1);
for(int j = 1; j < distance.cols; j++)
{
uint8 *pmin = pcur+j-1;
if((*(pafter+j)+2) < *pmin)
{
*pmin = *(pafter+j)+2;
}
if((*(pcur+j)+1) < *pmin)
{
*pmin = *(pcur+j)+1;
}
if((*(pafter+j-1)+1) < *pmin)
{
*pmin = *(pafter+j-1)+1;
}
}
}
return;
}
int main(int argc, char* argv[])
{
cv::Mat src, distance;
src.create(8,8, CV_8U);
distance.create(8,8, CV_8U);
for(int i = 0; i < distance.rows; i++)
{
uint8 *pTmp = distance.ptr<uint8>(i);
uint8 *pSrc = src.ptr<uint8>(i);
for(int j = 0; j < distance.cols; j++, pTmp++, pSrc++)
{
*pTmp = 0xf;
*pSrc = 0x0;
if(i == 0)
{
if(j == 6)
{
*pTmp = 0x0;
*pSrc = 0x1;
}
}
if(i > 0 && i < 4)
{
if(j == 5)
{
*pTmp = 0x0;
*pSrc = 0x1;
}
}
if(i == 4)
{
if(j==6 || j==1 || j==2)
{
*pTmp = 0x0;
*pSrc = 0x1;
}
}
if(i == 5)
{
if(j==7 || j==1)
{
*pTmp = 0x0;
*pSrc = 0x1;
}
}
if(i == 6 || i==7)
{
if(j==1)
{
*pTmp = 0x0;
*pSrc = 0x1;
}
}
}
}
for(int i = 0; i < distance.rows; i++)
{
uint8 *pTmp = distance.ptr<uint8>(i);
for(int j = 0; j < distance.cols; j++, pTmp++)
{
printf("%02x ", *pTmp);
}
printf("\n");
}
printf("\n");
for(int i = 0; i < src.rows; i++)
{
uint8 *pSrc= src.ptr<uint8>(i);
for(int j = 0; j < src.cols; j++, pSrc++)
{
printf("%02x ", *pSrc);
}
printf("\n");
}
printf("\n");
leftTop_mask_move(src, distance);
printf("after left top move\n");
for(int i = 0; i < distance.rows; i++)
{
uint8 *pTmp = distance.ptr<uint8>(i);
for(int j = 0; j < distance.cols; j++, pTmp++)
{
printf("%02x ", *pTmp);
}
printf("\n");
}
printf("\n");
rightTop_mask_move(src, distance);
for(int i = 0; i < distance.rows; i++)
{
uint8 *pTmp = distance.ptr<uint8>(i);
for(int j = 0; j < distance.cols; j++, pTmp++)
{
printf("%02x ", *pTmp);
}
printf("\n");
}
printf("\n");
return 0;
}
输出:
0f 0f 0f 0f 0f 0f 00 0f
0f 0f 0f 0f 0f 00 0f 0f
0f 0f 0f 0f 0f 00 0f 0f
0f 0f 0f 0f 0f 00 0f 0f
0f 00 00 0f 0f 0f 00 0f
0f 00 0f 0f 0f 0f 0f 00
0f 00 0f 0f 0f 0f 0f 0f
0f 00 0f 0f 0f 0f 0f 0f
00 00 00 00 00 00 01 00
00 00 00 00 00 01 00 00
00 00 00 00 00 01 00 00
00 00 00 00 00 01 00 00
00 01 01 00 00 00 01 00
00 01 00 00 00 00 00 01
00 01 00 00 00 00 00 00
00 01 00 00 00 00 00 00
after left top move
0f 0f 0f 0f 0f 0f 00 01
0f 0f 0f 0f 0f 00 01 02
0f 0f 0f 0f 0f 00 01 02
0f 0f 02 02 03 00 01 02
0f 00 00 01 02 01 00 01
0f 00 01 02 03 02 01 00
0f 00 01 02 03 03 02 01
0f 00 01 02 03 04 03 02
05 04 04 03 02 01 00 01
04 03 03 04 01 00 01 02
03 02 02 03 01 00 01 02
02 01 01 02 01 00 01 02
01 00 00 01 02 01 00 01
01 00 01 02 03 02 01 00
01 00 01 02 03 03 02 01
01 00 01 02 03 04 03 02