/// <summary>
/// 图形细化
/// </summary>
/// <param name="srcImg"></param>
/// <returns></returns>
public unsafe Bitmap ToThinner(Bitmap srcImg)
{
int iw = srcImg.Width;
int ih = srcImg.Height;
bool bModified; //二值图像修改标志
bool bCondition1; //细化条件1标志
bool bCondition2; //细化条件2标志
bool bCondition3; //细化条件3标志
bool bCondition4; //细化条件4标志
int nCount;
//5X5像素块
byte[,] neighbour = new byte[, ];
//新建临时存储图像
Bitmap NImg = new Bitmap(iw, ih, srcImg.PixelFormat);
bModified = true;
//细化修改标志, 用作循环条件
BitmapData dstData = srcImg.LockBits(new Rectangle(, , iw, ih), ImageLockMode.ReadWrite, srcImg.PixelFormat);
byte* data = (byte*)(dstData.Scan0);
//将图像转换为0,1二值得图像;
int step = dstData.Stride;
for (int i = ; i < dstData.Height; i++)
{
for (int j = ; j < dstData.Width * ; j += )
{
if (data[i * step + j] > )
//如果是白线条,只要将0改成1,将1改成0
data[i * step + j]
= data[i * step + j + ]
= data[i * step + j + ]
= ;
else
data[i * step + j]
= data[i * step + j + ]
= data[i * step + j + ]
= ;
}
} BitmapData dstData1 = NImg.LockBits(new Rectangle(, , iw, ih), ImageLockMode.ReadWrite, NImg.PixelFormat);
byte* data1 = (byte*)(dstData1.Scan0);
int step1 = dstData1.Stride;
//细化循环开始
while (bModified)
{
bModified = false;
//初始化临时二值图像NImg
for (int i = ; i < dstData1.Height; i++)
{
for (int j = ; j < dstData1.Width * ; j++)
{
data1[i * step1 + j] = ;
}
}
for (int i = ; i < ih - ; i++)
{
for (int j = ; j < iw * - ; j += )
{
bCondition1 = false;
bCondition2 = false;
bCondition3 = false;
bCondition4 = false;
if (data[i * step + j] == )
//若图像的当前点为白色,则跳过
continue;
for (int k = ; k < ; k++)
{
//取以当前点为中心的5X5块
for (int l = ; l < ; l++)
{
//1代表黑色, 0代表白色
//neighbour[k, l] = bw[i + k - 2, j + l - 2];
//neighbour[k, l] = data[(i + k - 2) * step + (j + l - 2)];
neighbour[k, l] = data[(i + k - ) * step + (j + l * - )];
}
}
//(1)判断条件2<=n(p)<=6
nCount = neighbour[, ] + neighbour[, ] + neighbour[, ] + neighbour[, ] + neighbour[, ] + neighbour[, ] + neighbour[, ] + neighbour[, ];
if (nCount >= && nCount <= )
bCondition1 = true;
else
{
data1[i * step1 + j] = ;
continue;
//跳过, 加快速度
}
//(2)判断s(p)=1
nCount = ;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (nCount == )
bCondition2 = true;
else
{
data1[i * step1 + j] = ;
continue;
}
//(3)判断p0*p2*p4=0 or s(p2)!=1
if (neighbour[, ] * neighbour[, ] * neighbour[, ] == )
bCondition3 = true;
else
{
nCount = ;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (nCount != )
//s(p2)!=1
bCondition3 = true;
else
{
data1[i * step1 + j] = ;
continue;
}
}
//(4)判断p2*p4*p6=0 or s(p4)!=1
if (neighbour[, ] * neighbour[, ] * neighbour[, ] == )
bCondition4 = true;
else
{
nCount = ;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (neighbour[, ] == && neighbour[, ] == )
nCount++;
if (nCount != )//s(p4)!=1
bCondition4 = true;
}
if (bCondition1 && bCondition2 && bCondition3 && bCondition4)
{
data1[i * step1 + j] = ;
bModified = true;
}
else
{
data1[i * step1 + j] = ;
}
}
}
// 将细化了的临时图像bw_tem[w,h]copy到bw[w,h],完成一次细化
for (int i = ; i < ih - ; i++)
for (int j = ; j < iw * - ; j++)
data[i * step + j] = data1[i * step1 + j];
}
for (int i = ; i < ih - ; i++)
{
for (int j = ; j < iw * - ; j += )
{
if (data[i * step + j] == ) data[i * step + j]
= data[i * step + j + ]
= data[i * step + j + ]
= ; else data[i * step + j]
= data[i * step + j + ]
= data[i * step + j + ]
= ; }
}
srcImg.UnlockBits(dstData);
NImg.UnlockBits(dstData1);
return (srcImg);
}

C# 指针操作图像 细化处理的更多相关文章

  1. C# 指针操作图像 二值化处理

    /// <summary> /// 二值化图像 /// </summary> /// <param name="bmp"></param& ...

  2. 【opencv】图像细化

    [原文:http://blog.csdn.net/qianchenglenger/article/details/19332011] 在我们进行图像处理的时候,有可能需要对图像进行细化,提取出图像的骨 ...

  3. 【OpenCV】三种方式操作图像像素

    OpenCV中,有3种访问每个像素的方法:使用at方法.使用迭代器方法.使用指针 运行如下程序后可以发现使用at方法速度最快. 代码如下: //操作图像像素 #include <opencv2/ ...

  4. OpenCV图像细化的一个例子

    转自:http://blog.csdn.net/zfdxx369/article/details/9091953?utm_source=tuicool 本文是zhang的一篇经典图像细化论文,效果很好 ...

  5. C#指针操作Marshal实例

    static void Main(string[] args) { ,,,}; ,,,}; IntPtr pt = Marshal.AllocHGlobal(a.Length); //从source数 ...

  6. C语言指针操作

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/pointer-manipulation. ...

  7. Day4:T1小技巧(类似于指针操作)T2搜索+小细节

    Day4:其中有很多小技巧get T1 一直没有听到过像这样的小技巧的略专业名词,有点类似于指针操作,之前有碰到过很多这样的题目 每次都是以不同的形式出现,但是感觉思想还是有点接近的吧(就比如某天有一 ...

  8. C语言数组操作和指针操作谁更高效

    在上一篇博文  代码优化小技巧(持续更新......) 第三条关于数组和指针谁更高效, 意犹未尽, 决定单独拉出一篇来讲 1. 数组和指针操作对比 #include <stdio.h> i ...

  9. Python 编程快速上手 第十七章 操作图像

    前言 在这一章节,讲了关于图像的三个方面的内容: 获得图像的相关信息:例如 RGBA 值,尺寸... 对图像进行编辑操作:例如 旋转,缩放... 在图像上绘制形状:例如 矩形,圆形... [Image ...

随机推荐

  1. Ubuntu里面软件的安装与卸载

    在Ubuntu里面,有时候碰到软件配置错了,这是重新再安装的话,会检测到已安装,系统不会再重新安装,就需要卸载之后重装 1.通过deb包安装的情况: 安装.deb包: 代码:sudo dpkg -i ...

  2. Qt 信号槽如何传递参数(或带参数的信号槽)

                                    信号槽如何传递参数(或带参数的信号槽) 利用Qt进行程序开发时,有时需要信号槽来完成参数传递.带参数的信号槽在使用时,有几点需要注意的地 ...

  3. mybatis Result Maps collection already contains value for com.ebways.dictionary.dao.impl.PtInfoDaoImpl.beanMap

    java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...

  4. ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)

    两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...

  5. Base64编码格式详解

    什么是Base64? 按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式.(The Base64 Content-T ...

  6. mybatis,批量新增、修改,删除

    转载自:http://blog.csdn.net/sanyuesan0000/article/details/19998727 最近需要用到Mybatis批量新增oracle数据库,刚开始在网上找到的 ...

  7. 解决 spring mvc 3.0 结合 hibernate3.2 使用<tx:annotation-driven>声明式事务无法提交的问题(转载)

    1.问题复现 spring 3.0 + hibernate 3.2 spring mvc使用注解方式:service使用@service注解 事务使用@Transactional 事务配置使用 < ...

  8. 一个servlet处理来自多个不同页面的请求!

    例如有一个用户表,我们要处理 添加,删除 用户以及登录功能 对应的有add.jsp del.jsp login.jsp等 <body> <!-- login.jsp --> & ...

  9. iOS蓝牙4.0

    iOS的蓝牙用到了  CoreBluetooth 框架 首先导入框架 #import <CoreBluetooth/CoreBluetooth.h> 我们需要一个管理者来管理蓝牙设备,CB ...

  10. iOS 设备的屏幕尺寸一览

    最近在做iPad开发项目 iPhone 设备: iPhone 1G --- 320x480iPhone 3G --- 320x480iPhone 3GS --- 320x480iPhone 4 --- ...