C# 指针操作图像 细化处理
/// <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# 指针操作图像 细化处理的更多相关文章
- C# 指针操作图像 二值化处理
/// <summary> /// 二值化图像 /// </summary> /// <param name="bmp"></param& ...
- 【opencv】图像细化
[原文:http://blog.csdn.net/qianchenglenger/article/details/19332011] 在我们进行图像处理的时候,有可能需要对图像进行细化,提取出图像的骨 ...
- 【OpenCV】三种方式操作图像像素
OpenCV中,有3种访问每个像素的方法:使用at方法.使用迭代器方法.使用指针 运行如下程序后可以发现使用at方法速度最快. 代码如下: //操作图像像素 #include <opencv2/ ...
- OpenCV图像细化的一个例子
转自:http://blog.csdn.net/zfdxx369/article/details/9091953?utm_source=tuicool 本文是zhang的一篇经典图像细化论文,效果很好 ...
- C#指针操作Marshal实例
static void Main(string[] args) { ,,,}; ,,,}; IntPtr pt = Marshal.AllocHGlobal(a.Length); //从source数 ...
- C语言指针操作
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/pointer-manipulation. ...
- Day4:T1小技巧(类似于指针操作)T2搜索+小细节
Day4:其中有很多小技巧get T1 一直没有听到过像这样的小技巧的略专业名词,有点类似于指针操作,之前有碰到过很多这样的题目 每次都是以不同的形式出现,但是感觉思想还是有点接近的吧(就比如某天有一 ...
- C语言数组操作和指针操作谁更高效
在上一篇博文 代码优化小技巧(持续更新......) 第三条关于数组和指针谁更高效, 意犹未尽, 决定单独拉出一篇来讲 1. 数组和指针操作对比 #include <stdio.h> i ...
- Python 编程快速上手 第十七章 操作图像
前言 在这一章节,讲了关于图像的三个方面的内容: 获得图像的相关信息:例如 RGBA 值,尺寸... 对图像进行编辑操作:例如 旋转,缩放... 在图像上绘制形状:例如 矩形,圆形... [Image ...
随机推荐
- Sparse Matrix Multiplication
Given two sparse matrices A and B, return the result of AB. You may assume that A's column number is ...
- 错误描述:请求“System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”类型的权限已失败
错误描述:请求“System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, Pu ...
- Light OJ 1068
数位DP #include <cstdio> #include <cstring> using namespace std; ; ; long long n; int f[MA ...
- Java 多线程Socket编程通讯--实现聊天室代码
1.创建服务器类 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import ja ...
- Unity3d 防止内存修改工具的小方法
一个非常简单的方法,直接上代码. private int curATK; private int curAtkKey; public int CurATK { get { return curATK ...
- 解读Unity中的CG编写Shader系列七(不透明度与混合)
转自http://www.itnose.net/detail/6098539.html 1.不透明度 当我们要将两个半透的纹理贴图到一个材质球上的时候就遇到混合的问题,由于前面的知识我们已经知道了片段 ...
- ios 跟踪UITextField更改的简单方法
如图,用xib链接,用到的消息是Editing Changed 消息.
- 使用Servlet和jdbc创建用户登录验证
首先创建一个用户表,用来保存用户名 密码,并插入几条数据 mysql> desc user;+----------+-------------+------+-----+---------+-- ...
- 请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间【转】
本文来自:http://www.woqutech.com/?p=1116 MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之 ...
- codeforces 515A.Drazil and Date 解题报告
题目链接:http://codeforces.com/problemset/problem/515/A 题目意思:问能否从 (0, 0) 出发,恰好走 s 步,到达该位置(a, b). 首先容易知道, ...