链码表追踪二值图像的最外层轮廓
来源:互联网 发布:乾隆下江南 知乎 编辑:程序博客网 时间:2024/06/05 17:52
链码的优越性在于:对于上一个链码方向逆时针旋转120度,开始查找下一个方向,然后顺时针一次查找八个方向,直到找到符合条件的点,再开始下一轮的查找
代码:
#include <iostream>#include <string>#include "gdal_priv.h"using namespace std;/********************************************************* 根据容差判断两像素颜色是否相近* 参数c1、c2为两种颜色信息,delta为容差********************************************************/bool IsSameColor(unsigned char c1, unsigned char c2, int delta){ return ( abs(c1 - c2) < delta);}/******************************************************************************** 寻找下一轮廓点* 参数:imageBuf为要搜索的图形,w、h为图像尺寸,x、y为当前边界点坐标 n为上一轮廓点到当前轮廓点的链码,color为区域的颜色*******************************************************************************/int NextPoint(unsigned char** imageBuf, int w, int h, int y, int x, int n, unsigned char color){ int directData[8][2] //链码向量表 ={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}}; int startIndex = n + 3 + 8; //确定起始链码,对于上一个链码方向旋转120度,开始查找下一个方向,然后顺时针一次查找八个方向,直到找到符合条件的点 int i; //对邻域进行搜索 for(i = 0;i <= 7;i++) { int index = (startIndex - i) % 8; int nx = x + directData[index][0]; int ny = y + directData[index][1]; //判断边界点 if(nx >= 0 && nx < w && ny >= 0 && ny < h) if( IsSameColor(imageBuf[ny][nx],color,1) ) { return index; } } //如果没找到新的边界点返回错误信息 return 9; }/***************************************************************** 单区域的轮廓跟踪* 参数:imageBuf为跟踪的图像,w、h为图像尺寸,x、y为搜索起始点,* n为起始链码,color为区域颜色****************************************************************/int* SingleTrack(unsigned char** imageBuf, int w, int h, int y, int x, int n, unsigned char color){ int directData[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};//链码向量表 int* track = new int[9999]; //为链码表开辟存储单元 int k = 0; int nx = x,ny = y; int index = n; //保存起始点坐标 track[0] = y; track[1] = x; //循环搜索下一边界点 直到回到起始点 do { index = NextPoint(imageBuf,w,h,ny,nx,index,color); if(index == 9) break; track[k+3] = index; k++; nx += directData[index][0]; ny += directData[index][1]; } while( nx!=x || ny!=y ); track[2] = k; //记录链码表的长度 return track;}//用链码表追踪图像的轮廓//track为链码表,track[0],track[1]分别存放的是起始轮廓的坐标(y,x),track[2]存放链码表的长度,后面的为轮廓上每个点的链码值//一定要注意x,y的本别对应关系,y对应Height,x对应Width,这一点很容易出现内存异常int main(){ GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); string str1="1.1.bmp"; string str2="1.2.bmp"; GDALDataset* pInDataset=(GDALDataset*)GDALOpen(str1.data() ,GA_ReadOnly); if(pInDataset == nullptr) { cout<<"未找到输入图像"<<endl; getchar(); return 1; } int Width=pInDataset->GetRasterXSize(); int Height = pInDataset->GetRasterYSize(); int band = pInDataset->GetRasterCount(); //double dGeoTrans[6]={}; //pInDataset->GetGeoTransform(dGeoTrans); //const char* cProjectionRef = pInDataset->GetProjectionRef(); unsigned char* Image = new unsigned char[Width * Height]; memset(Image,0,sizeof(unsigned char) * Width * Height); GDALRasterBand* pRasterBand = pInDataset->GetRasterBand(1); CPLErr err=pRasterBand->RasterIO(GF_Read ,0 ,0 ,Width ,Height ,Image ,Width ,Height ,GDT_Byte ,0 ,0); unsigned char** ImageBuf = new unsigned char* [Height]; for(int i = 0;i < Height;++i) { ImageBuf[i] = new unsigned char[Width]; memset(ImageBuf[i],0,sizeof(unsigned char) * Width); } //int a ,b; //int flag = 0; for(int i = 0;i < Height;++i) { for(int j = 0;j < Width;++j) { ImageBuf[i][j] = Image[i * Width + j]; //if(flag == 0) //{ // if(ImageBuf[i][j] == 255) //} } } //为检测一张特定的图像,设定的(0,794)该坐标点。为任意轮廓即可 unsigned char color = ImageBuf[0][794]; int* track = SingleTrack(ImageBuf,Width,Height,0,794,0,color); //for(int i = 0;i < track[2];++i) //{ // cout<<track[i]<<endl; //} unsigned char* OutImage = new unsigned char[Width * Height]; memset(OutImage,0,sizeof(unsigned char) * Width * Height); int directData[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};//链码向量表 int y = track[0]; int x = track[1]; for(int i = 3;i < track[2];++i) { OutImage[y * Width + x] = 255; x += directData[track[i]][0]; y += directData[track[i]][1]; } GDALDriver* pOutDriver = GetGDALDriverManager()->GetDriverByName("BMP"); GDALDataset* pOutDataset = pOutDriver->Create(str2.data() ,Width ,Height ,1 ,GDT_Byte ,NULL); GDALRasterBand* pOutRasterband=pOutDataset->GetRasterBand(1); pOutRasterband->RasterIO(GF_Write ,0 ,0 ,Width ,Height ,OutImage ,Width ,Height ,GDT_Byte ,0 ,0); delete Image; for(int i = 0;i < Height;++i) { delete ImageBuf[i]; } delete ImageBuf; delete OutImage; GDALClose(pInDataset); GDALClose(pOutDataset); GetGDALDriverManager()->DeregisterDriver(pOutDriver); system("pause"); return 0;}
1 0
- 链码表追踪二值图像的最外层轮廓
- 图像基础---二值图像的轮廓提取
- 二值图像轮廓跟踪
- 二值图像轮廓提取
- 二值图像轮廓提取
- 二值图像轮廓提取
- 二值图像轮廓填充
- Opencv获取二值图像轮廓
- 图像分析:二值图像连通域标记2-基于轮廓的标记
- OpenCV图像的轮廓与链码
- OpenCV 基于轮廓提取的二值图像分析与连通区域标记算法
- OpenCV图像的轮廓
- 图像的轮廓检测
- 图像轮廓的提取
- 使用Matlab对二值图像进行轮廓提取
- 使用Matlab对二值图像进行轮廓提取
- Matlab对二值图像进行轮廓提取
- 使用Matlab对二值图像进行轮廓提取
- C语言学习要点
- Codeforces Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)
- 第五周项目二(3)计算工资
- AndroidStudio怎样和Git关联
- 最大权闭合子图——hiho 119周
- 链码表追踪二值图像的最外层轮廓
- 基于BI应用的数据仓库建模归纳
- ibatis的sqlSessionTemplate实例的sqlSession接口定义。
- shell if-else
- iOS Label分段设置颜色
- 初步了解jquery mobile
- Unreal Engine 4/虚幻4 视频纹理或者在关卡中播放视频
- Palindrome Number
- python https server and client