一种细化算法及其与opencv的实现

本文介绍了一种图像细化算法,该算法通过分析像素点的8个相邻点来决定保留或删除该点。具体实现中,利用索引值进行查表操作,若查得结果为0,则保留该像素点,否则进行删除。配合OpenCV库,可以有效地应用到图像处理中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

是根据图像中像素点得八个相邻点得情况,得到一个索引值,然后查表,如果为0怎保留该点,否则删除

算法代码:

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include<iostream>
#include<fstream>
#include<iomanip>

using namespace std;

static int erasetable[256] = {
	0,0,1,1,0,0,1,1,     1,1,0,1,1,1,0,1,
	1,1,0,0,1,1,1,1,     0,0,0,0,0,0,0,1,
	0,0,1,1,0,0,1,1,     1,1,0,1,1,1,0,1,
	1,1,0,0,1,1,1,1,     0,0,0,0,0,0,0,1,
	1,1,0,0,1,1,0,0,     0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,     0,0,0,0,0,0,0,0,
	1,1,0,0,1,1,0,0,     1,1,0,1,1,1,0,1,
	0,0,0,0,0,0,0,0,     0,0,0,0,0,0,0,0,
	0,0,1,1,0,0,1,1,     1,1,0,1,1,1,0,1,
	1,1,0,0,1,1,1,1,     0,0,0,0,0,0,0,1,
	0,0,1,1,0,0,1,1,     1,1,0,1,1,1,0,1,
	1,1,0,0,1,1,1,1,     0,0,0,0,0,0,0,0,
	1,1,0,0,1,1,0,0,     0,0,0,0,0,0,0,0,
	1,1,0,0,1,1,1,1,     0,0,0,0,0,0,0,0,
	1,1,0,0,1,1,0,0,     1,1,0,1,1,1,0,0,
	1,1,0,0,1,1,1,0,     1,1,0,0,1,0,0,0
};//这个表是检测是用来细化黑色点边缘的,若为0则保留,否则删除,如果用来细化白色点边缘的话就取fan
/******************************************************************888
函数名:save
参数类型:void
功能:保存细化查询表
****************************************************************************/
void save()
{
	fstream writefile("erasetable.txt" , ios::out);
	int n=0;
	for(int i=0;i<256;i++)
	{
            writefile<<setw(2)<<erasetable[i];
	}
	writefile<<endl;
}
/**********************************************************88
函数名:npow
参数类型:int n
功能:求2的n次方并返回结果
返回值类型:int
***************************************************************/
int npow(int n)
{
	int mul = 1;
	for(int i=0;i<n;i++)
	{
		mul *= 2;
	}
	return mul;
}
/***************************************************************************
函数名:Threshold
参数类型:IplImage *src , int lower , int higher
功能:二值化灰度图像
*******************************************************************************/
void Threshold(IplImage *src , int lower , int higher)
{
	assert(src->nChannels==1);
	for(int h=0;h<src->height;h++)
		for(int w=0;w<src->width;w++)
		{
			if(*(src->imageData +h*src->widthStep+w)>0&&*(src->imageData+h*src->widthStep+w)<87)
				*(src->imageData +h*src->widthStep+w) = 255;
			else
				*(src->imageData +h*src->widthStep+w) = 0;

		}
}
/*****************************************************************************8
函数名:scantable
参数类型:IplImage *src
功能:扫描像素8领域周围的八个像素值(只检测白色点得周围),像素值为0置1,否则为0,并保存(如果是检测黑色的周围的话就相反),
再根据得到的数,将得到的数看做一个二进制数化为十进制的数,这个值即为查询索引,如果查到的值为0则保留,否则删除
***************************************************************************************/
void scantable(IplImage *src)
{
	assert(src->nChannels==1);
	int scan[8] = {0};
	for(int h=1;h<(src->height-1);h++)
	{
		for(int w=1;w<(src->width-1);w++)
		{
			int index = 0;
			if(*(src->imageData+(h)*src->widthStep+w)!=0)
			{
			if(*(src->imageData+(h-1)*src->widthStep+w-1)==0)
				scan[0] = 1;
			else
				scan[0] = 0;
			if(*(src->imageData+(h-1)*src->widthStep+w)==0)
				scan[1] = 1;
			else
				scan[1] = 0;
			if(*(src->imageData+(h-1)*src->widthStep+w+1)==0)
				scan[2] = 1;
			else
				scan[2] = 0;
			if(*(src->imageData+(h)*src->widthStep+w-1)==0)
				scan[3] = 1;
			else
				scan[3] = 0;
			if(*(src->imageData+(h)*src->widthStep+w+1)==0)
				scan[4] = 1;
			else
				scan[4] = 0;
			if(*(src->imageData+(h+1)*src->widthStep+w-1)==0)
				scan[5] = 1;
			else
				scan[5] = 0;
			if(*(src->imageData+(h+1)*src->widthStep+w)==0)
				scan[6] = 1;
			else
				scan[6] = 0;
			if(*(src->imageData+(h+1)*src->widthStep+w+1)==0)
				scan[7] = 1;
			else
				scan[7] = 0;
	   

			for(int i=0;i<8;i++)
			{
				index += scan[i]*npow(i);
			}
          //  printf("%d\n" ,index);
			if(erasetable[index] == 1)
			{
				//printf("%d\n" , erasetable[index]);
                *(src->imageData+h*src->widthStep+w) = 0;
			}
			}

		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	save();
	IplImage *img = 0;
	IplImage *gray = 0;
	IplImage *copy_gray = 0;
	int vmin = 0;
	int vmax = 0;

	img = cvLoadImage("1.bmp" , 1);
	gray = cvCreateImage(cvGetSize(img) , 8 , 1);
	copy_gray = cvCreateImage(cvGetSize(img) , 8 ,1);

	cvCvtColor(img , gray , CV_BGR2GRAY);
	cvSmooth(gray , gray , CV_MEDIAN , 3 , 0 , 0 , 0);

	cvNamedWindow("gray" , 1);
	cvNamedWindow("erase" , 1);
	//cvCreateTrackbar("lower" , "gray" , &vmin , 256 , 0);
	//cvCreateTrackbar("higher" , "gray" , &vmax , 256 , 0);

     Threshold(gray , vmin , vmax);
	 cvCopy(gray , copy_gray);
     scantable(copy_gray);
		cvShowImage("gray" , gray);
		cvShowImage("erase" , copy_gray);

		if(cvWaitKey(0)==27)
		{
          cvReleaseImage(&img);
		  cvReleaseImage(&gray);
		  cvReleaseImage(©_gray);
		}


	return 0;
}


 

 原图:

 

效果图:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值