源图
解析图,绿色的是主边界,红色的是和主边界形成的平行四边形的两条对边,在两条对边进行精确查找得出两条最终的对边
区域图
校正图
二值图
网格图
解码图
//牵连的代码不下5000行,所以只贴主代码了,有思路就行
using System;
namespace ImageProcessing.Graph
{
//表示范围的类
[Serializable]
public class Range : ICloneable, IComparable
{
public Range() { }
public Range(double max) { end = max; sort(); }
public Range(double begin, double end) { this.begin = begin; this.end = end; sort(); }
double begin = 0, end = 0;
public double End
{
get { return end; }
set { end = value; sort(); }
}
public double Begin
{
get { return begin; }
set { begin = value; sort(); }
}
public double Center
{
get { return (begin + end) / 2d; }
}
public double Lenght
{
get { return Math.Abs(end - begin); }
}
public Range clone
{
get { return new Range(begin, end); }
}
void sort()
{
if (end < begin)
GraphHelper.Swap(ref begin, ref end);
}
public static Range FromSize(double begine,double length)
{
return new Range(begine, begine + length);
}
public object Clone() { return clone; }
public double DistanceTo(Range dest)
{
if (IntersectWith(dest)) return 0;
if (begin > dest.end) return begin - dest.end;
return dest.begin - end;
}
public double CenterDistanctTo(Range dest)
{
return Math.Abs(Center - dest.Center);
}
public double DistanceTo(double pos)
{
if (pos >= begin && pos <= end) return 0;
else if (pos < begin) return begin - pos;
else return pos - end;
}
public Range Join(Range dest)
{
return new Range(Math.Min(begin, dest.begin), Math.Max(end, dest.end));
}
public Range Intersect(Range dest)
{
if (!IntersectWith(dest)) { return null; }
else if (Contains(dest)) return clone;
return new Range(Math.Max(begin, dest.begin), Math.Min(end, dest.end));
}
public bool Contains(double d)
{
return d >= begin && d <= end;
}
public bool Contains(Range dest)
{
return dest.begin >= this.begin && dest.end <= end;
}
public bool IntersectWith(Range dest)
{
return !(dest.begin > end || dest.end < begin);
}
public static bool operator ==(Range range1, Range range2)
{
if (Equals(range1,null)) return Equals(range2,null);
else if (Equals(range2, null)) return false;
return range1.begin == range2.begin && range1.end == range2.end;
}
public static bool operator !=(Range range1, Range range2)
{
return !(range1 == range2);
}
public override bool Equals(object obj)
{
if (Equals(obj, null)) return false;
if (!(obj is Range)) return false;
return this == (Range)obj;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override string ToString()
{
return string.Format("[{0},{1}]", begin, end);
}
public int CompareTo(object obj)
{
Range dest = (Range)obj;
if (begin < dest.begin)
return -1;
else if (begin == dest.begin)
{
if (this.end == dest.end)
return 0;
else if (this.end < dest.end)
return -1;
else
return 1;
}
else
return 1;
}
}
}
//这3个函数的作用是扫描线段上的指定颜色区域,所属的类为静态类GraphHelper,这个类有3000行,没必要的就不复制了呵呵
class GraphHelper
{
public static List<Line> GetIntersectLines(byte[] threshBuffers, int imgWidth, int imgHeight, bool seachBlackPixel, Line l)
{
RectD rd = new RectD(0, 0, imgWidth, imgHeight);
if (l.StartPos.X >= 0 && l.StartPos.Y >= 0 && l.StartPos.X < imgWidth && l.StartPos.Y < imgHeight)
{
return GetIntersectLines(threshBuffers, imgWidth, imgHeight, seachBlackPixel, l.StartPos, l.Direction, l.Length);
}
else if (l.EndPos.X >= 0 && l.EndPos.Y >= 0 && l.EndPos.X < imgWidth && l.EndPos.Y < imgHeight)
{
return GetIntersectLines(threshBuffers, imgWidth, imgHeight, seachBlackPixel, l.EndPos, l.Direction * -1, l.Length);
}
else
{
List<PointD> pds = rd.GetIntersect(l);
if (pds.Count == 2)
return GetIntersectLines(threshBuffers, imgWidth, imgHeight, seachBlackPixel, pds[0], pds[1] - pds[0], pds[0].DistanceTo(pds[1]));
}
return new List<Line>();
}
/// <summary>
/// 单纯计算起始点沿着dir方向上的与指定颜色区域的的相交线段,如果起始点不在范围内则直接中断
/// </summary>
public static List<Line> GetIntersectLines(byte[] threshBuffers, int imgWidth, int imgHeight, bool seachBlackPixel, PointD startPos, PointD direction, double length)
{
int px = seachBlackPixel ? 0 : 1;
List<Line> res = new List<Line>();
PointD cur = startPos.clone, last = null, prev = null;
PointD dir = direction.Unit;
Point pt;
pt = cur.Point;
while (InRange(pt, imgWidth, imgHeight))
{
if (threshBuffers[pt.X + pt.Y * imgWidth] == px)
{
last = cur.clone;
prev = cur.clone;
cur += dir;
pt = cur.Point;
while (InRange(pt, imgWidth, imgHeight) && threshBuffers[pt.X + pt.Y * imgWidth] == px)
{
prev = cur;
cur += dir;
pt = cur.Point;
}
res.Add(new Line(last, prev));
}
cur += dir;
pt = cur.Point;
}
return res;
}
//查找行或列扫描线上的颜色区域段
public static List<Range> GetStrideRanges(byte[] threshBuffers, int imgWidth, int imgHeight, bool searchBlackPixel, int position, bool searchRow)
{
return GetStrideIntersectLines(threshBuffers, imgWidth, imgHeight, searchBlackPixel, position, searchRow)
.ConvertAll<Range>(delegate(Line line)
{
if (searchRow) return new Range(line.StartPos.X, line.EndPos.X);
else return new Range(line.StartPos.Y, line.EndPos.Y);
});
}
public static List<Line> GetStrideIntersectLines(byte[] threshBuffers, int imgWidth, int imgHeight, bool seachBlackPixel, int position, bool searchRow)
{
PointD start = searchRow ? new PointD(0, position) : new PointD(position, 0);
PointD dir = searchRow ? new PointD(1, 0) : new PointD(0, 1);
return GetIntersectLines(threshBuffers, imgWidth, imgHeight, seachBlackPixel, start, dir, searchRow ? imgWidth : imgHeight);
}
}
//高斯模糊矩阵类
using System;
namespace ImageProcessing.Base.Imaging
{
public class GaussainMatrix
{
public GaussainMatrix(double sigma, int size)
{
size |= 1;
this.size = size;
this.width = size;
this.height = size;
datas = new double[size, size];
int cx = size / 2, cy = size / 2;
double dx, dy;
double sum = 0;
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
dx = x - cx; dy = y - cy;
datas[y, x] = Math.Exp(-1.0 * (dx * dx + dy * dy) / (2.0 * sigma * sigma)) / (Math.Sqrt(2.0 * Math.PI) * sigma);