using RichCreator.Utility.Structs;
|
using Emgu.CV;
|
using Emgu.CV.CvEnum;
|
using Emgu.CV.Structure;
|
using Emgu.CV.Util;
|
using System;
|
using System.Collections.Generic;
|
using System.Drawing;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using Orientation = RichCreator.Utility.Structs.Orientation;
|
using RichCreator.Utility.Captures;
|
|
namespace RichCreator.Utility.CV
|
{
|
/// <summary>
|
/// 图像识别类
|
/// </summary>
|
public static class CVHelper
|
{
|
#region 找线
|
/// <summary>
|
/// 查找线
|
/// </summary>
|
/// <param name="line"></param>
|
/// <param name="image"></param>
|
/// <param name="minSize"></param>
|
/// <param name="orientation"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <returns></returns>
|
public static bool FindLine(out ZTLine line, Image<Rgb, byte> image, Int32 minSize, Orientation orientation, ZTHsvFloatColor minColor, ZTHsvFloatColor maxColor)
|
{
|
ZTRectangle limitRect = new ZTRectangle(0, 0, image.Width - 1, image.Height - 1);
|
return FindLine(out line, image, minSize, limitRect, orientation, minColor, maxColor);
|
}
|
|
/// <summary>
|
/// 查找线
|
/// </summary>
|
/// <param name="line"></param>
|
/// <param name="image"></param>
|
/// <param name="minSize"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="orientation"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <returns></returns>
|
public static bool FindLine(out ZTLine line, Image<Rgb, byte> image, Int32 minSize, ZTRectangle limitRectangle, Orientation orientation, ZTHsvFloatColor minColor, ZTHsvFloatColor maxColor)
|
{
|
line = ZTLine.Empty;
|
Int32 start, size;
|
|
Int32 xStep = 1;
|
Int32 yStep = 1;
|
if (minSize > 0)
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
xStep = minSize - 1;
|
}
|
|
if (orientation == Orientation.Vertical)
|
{
|
yStep = minSize - 1;
|
}
|
}
|
|
|
|
|
for (int y = limitRectangle.Start.Y; y <= limitRectangle.End.Y; y += yStep)
|
{
|
for (int x = limitRectangle.Start.X; x <= limitRectangle.End.X; x += xStep)
|
{
|
if (InRange(image.Data, x, y, minColor,maxColor))
|
{
|
if (GetLineInfo(out start, out size, image, new ZTPoint(x, y), minSize,orientation, minColor, maxColor))
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
line = new ZTLine(start, y, size);
|
}
|
else
|
{
|
line = new ZTLine(x, start, size);
|
}
|
return true;
|
}
|
}
|
}
|
}
|
|
return false;
|
}
|
|
/// <summary>
|
/// 查找线
|
/// </summary>
|
/// <param name="image"></param>
|
/// <param name="minSize"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="orientation"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <returns></returns>
|
public static List<ZTLine> FindLines( Image<Rgb, byte> image, Int32 minSize, ZTRectangle limitRectangle, Orientation orientation, ZTHsvFloatColor minColor, ZTHsvFloatColor maxColor)
|
{
|
List<ZTLine> lines = new List<ZTLine>();
|
Func<Int32, Int32, bool> existsPoint = (x, y) => {
|
for (Int32 i = 0; i < lines.Count; i++)
|
{
|
if (lines[0].Contain(x, y, orientation))
|
{
|
return true;
|
}
|
}
|
return false;
|
};
|
|
ZTLine line = ZTLine.Empty;
|
Int32 start, size;
|
|
Int32 xStep = 1;
|
Int32 yStep = 1;
|
if (minSize > 0)
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
xStep = minSize - 1;
|
}
|
|
if (orientation == Orientation.Vertical)
|
{
|
yStep = minSize - 1;
|
}
|
}
|
|
for (int y = limitRectangle.Start.Y; y <= limitRectangle.End.Y; y += yStep)
|
{
|
for (int x = limitRectangle.Start.X; x <= limitRectangle.End.X; x += xStep)
|
{
|
if (InRange(image.Data, x, y, minColor, maxColor))
|
{
|
//存在,即跳过
|
if (existsPoint(x, y))
|
{
|
continue;
|
}
|
|
if (GetLineInfo(out start, out size, image, new ZTPoint(x, y), minSize, orientation, minColor, maxColor))
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
line = new ZTLine(start, y, size);
|
}
|
else
|
{
|
line = new ZTLine(x, start, size);
|
}
|
lines.Add(line);
|
}
|
}
|
}
|
}
|
|
return lines;
|
}
|
|
/// <summary>
|
/// 线信息
|
/// </summary>
|
/// <param name="image">图片</param>
|
/// <param name="x">参考点</param>
|
/// <param name="y"></param>
|
/// <param name="minSize">线的最小长度,如果找到的线比这个小就舍弃</param>
|
/// <param name="color">要找的线的颜色</param>
|
/// <param name="start">起点X</param>
|
/// <param name="size">长度</param>
|
/// <returns></returns>
|
private static bool GetLineInfo(out Int32 start, out Int32 size, Image<Rgb, byte> image, ZTPoint point, Int32 minSize, Orientation orientation, ZTHsvFloatColor minColor,ZTHsvFloatColor maxColor)
|
{
|
start = orientation == Orientation.Horizontal ? point.X : point.Y;
|
Int32 end = start;
|
Int32 current = start;
|
bool result = true;
|
|
//往前捯,找起点
|
for (int i = current; i >= 0; i--)
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
result = InRange(image.Data, i, point.Y,minColor,maxColor);
|
}
|
else
|
{
|
result = InRange(image.Data, point.X, i,minColor,maxColor);
|
}
|
|
|
if (!result)
|
{
|
break;
|
}
|
start = i;
|
}
|
|
//往后捯,找终点
|
current = (orientation == Orientation.Horizontal ? point.X : point.Y) + 1;
|
for (int i = current; i < image.Width; i++)
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
result = InRange(image.Data, i, point.Y, minColor, maxColor);
|
}
|
else
|
{
|
result = InRange(image.Data, point.X, i, minColor, maxColor);
|
}
|
|
if (!result)
|
{
|
break;
|
}
|
end = i;
|
}
|
|
size = end - start + 1;
|
if (size >= minSize)
|
{
|
return true;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 查找线
|
/// </summary>
|
/// <param name="image"></param>
|
/// <param name="color"></param>
|
/// <param name="minSize"></param>
|
/// <param name="line"></param>
|
/// <returns></returns>
|
public static bool FindLine(out ZTLine line,Image<Rgb, byte> image, Int32 minSize,Orientation orientation, params ZTColor[] colors)
|
{
|
ZTRectangle limitRect = new ZTRectangle(0, 0, image.Width - 1, image.Height - 1);
|
return FindLine(out line, image, minSize, limitRect,orientation, colors);
|
}
|
|
/// <summary>
|
/// 查找线
|
/// </summary>
|
/// <param name="image"></param>
|
/// <param name="color"></param>
|
/// <param name="minSize"></param>
|
/// <param name="line"></param>
|
/// <param name="limitRectangle"></param>
|
/// <returns></returns>
|
public static bool FindLine(out ZTLine line, Image<Rgb, byte> image, Int32 minSize, ZTRectangle limitRectangle,Orientation orientation,params ZTColor[] colors)
|
{
|
line = ZTLine.Empty;
|
Int32 start, size;
|
|
Int32 xStep = 1;
|
Int32 yStep = 1;
|
if (minSize > 0)
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
xStep = minSize - 1;
|
}
|
|
if (orientation == Orientation.Vertical)
|
{
|
yStep = minSize - 1;
|
}
|
}
|
|
|
|
|
for (int y = limitRectangle.Start.Y; y <= limitRectangle.End.Y; y+=yStep)
|
{
|
for (int x = limitRectangle.Start.X; x <= limitRectangle.End.X; x += xStep)
|
{
|
if (CompareColors(image.Data, x, y, orientation, colors))
|
{
|
if (GetLineInfo(out start, out size,image, new ZTPoint(x, y), minSize,orientation, colors))
|
{
|
|
if (orientation == Orientation.Horizontal)
|
{
|
line = new ZTLine(start, y, size);
|
}
|
else
|
{
|
line = new ZTLine(x, start, size);
|
}
|
return true;
|
}
|
}
|
}
|
}
|
|
return false;
|
}
|
|
|
/// <summary>
|
/// 线信息
|
/// </summary>
|
/// <param name="image">图片</param>
|
/// <param name="x">参考点</param>
|
/// <param name="y"></param>
|
/// <param name="minSize">线的最小长度,如果找到的线比这个小就舍弃</param>
|
/// <param name="color">要找的线的颜色</param>
|
/// <param name="start">起点X</param>
|
/// <param name="size">长度</param>
|
/// <returns></returns>
|
private static bool GetLineInfo(out Int32 start, out Int32 size,Image<Rgb, byte> image, ZTPoint point, Int32 minSize,Orientation orientation, ZTColor[] colors)
|
{
|
start =orientation==Orientation.Horizontal? point.X:point.Y;
|
Int32 end = start;
|
Int32 current = start;
|
bool result = true;
|
for (int i = current; i >= 0; i--)
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
result = CompareColors(image.Data, i, point.Y, orientation, colors);
|
}
|
else
|
{
|
result = CompareColors(image.Data, point.X, i, orientation, colors);
|
}
|
|
|
if (!result)
|
{
|
break;
|
}
|
start = i;
|
}
|
|
current = (orientation == Orientation.Horizontal ? point.X : point.Y) + 1;
|
for (int i = current; i < image.Width; i++)
|
{
|
if (orientation == Orientation.Horizontal)
|
{
|
result = CompareColors(image.Data, i, point.Y, orientation, colors);
|
}
|
else
|
{
|
result = CompareColors(image.Data, point.X, i, orientation, colors);
|
}
|
|
if (!result)
|
{
|
break;
|
}
|
end = i;
|
}
|
|
size = end - start + 1;
|
if (size >= minSize)
|
{
|
return true;
|
}
|
return false;
|
}
|
|
|
#endregion
|
|
#region 查找方框
|
|
/// <summary>
|
/// 查找方框
|
/// </summary>
|
/// <param name="rectangle"></param>
|
/// <param name="image"></param>
|
/// <param name="minSize"></param>
|
/// <param name="maxRadius"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <returns></returns>
|
public static bool FindRectangle(out ZTRectangle rectangle, Image<Rgb, byte> image, ZTSize minSize, Int32 maxRadius, ZTHsvFloatColor minColor,ZTHsvFloatColor maxColor)
|
{
|
ZTRectangle limitRect = new ZTRectangle(0, 0, image.Width - 1, image.Height - 1);
|
return FindRectangle(out rectangle, image, minSize, maxRadius, limitRect, minColor,maxColor);
|
}
|
|
/// <summary>
|
/// 查找方框
|
/// </summary>
|
/// <param name="rectangle"></param>
|
/// <param name="image"></param>
|
/// <param name="minSize"></param>
|
/// <param name="maxRadius"></param>
|
/// <param name="limitRect"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <returns></returns>
|
public static bool FindRectangle(out ZTRectangle rectangle, Image<Rgb, byte> image, ZTSize minSize, Int32 maxRadius, ZTRectangle limitRect, ZTHsvFloatColor minColor, ZTHsvFloatColor maxColor)
|
{
|
rectangle = default(ZTRectangle);
|
ZTLine topLine = ZTLine.Empty;
|
ZTLine top = default(ZTLine);
|
|
//查找顶部线
|
ZTRectangle limit = limitRect;
|
if (!FindLine(out top, image, minSize.Width, limit, Orientation.Horizontal, minColor,maxColor))
|
{
|
return false;
|
}
|
|
//查找左边线
|
ZTLine left = default(ZTLine);
|
limit = new ZTRectangle(
|
Math.Max(limitRect.Start.X, top.X - maxRadius),
|
top.Y,
|
top.X + top.Length - minSize.Width,
|
limitRect.End.Y
|
);
|
if (!FindLine(out left, image, minSize.Height, limit, Orientation.Vertical, minColor, maxColor))
|
{
|
return false;
|
}
|
|
|
//查找右边线
|
ZTLine right = default(ZTLine);
|
limit = new ZTRectangle(
|
top.X + minSize.Width,
|
top.Y,
|
Math.Min(limitRect.End.X, top.X + top.Length + maxRadius),
|
limitRect.End.Y
|
);
|
if (!FindLine(out right, image, minSize.Height, limit, Orientation.Vertical, minColor, maxColor))
|
{
|
return false;
|
}
|
|
if (Math.Abs(left.Length- right.Length)> maxRadius)
|
{
|
return false;
|
}
|
|
//查找下边线
|
ZTLine down = default(ZTLine);
|
limit = new ZTRectangle(
|
left.X,
|
top.Y + minSize.Height,
|
right.X,
|
Math.Min(limitRect.End.Y, right.Y + right.Length + maxRadius)
|
);
|
if (!FindLine(out down, image, minSize.Width, limit, Orientation.Horizontal, minColor, maxColor))
|
{
|
return false;
|
}
|
|
if (top.Length != down.Length)
|
{
|
return false;
|
}
|
rectangle = new ZTRectangle(left.X, top.Y, right.X, down.Y);
|
return true;
|
}
|
|
/// <summary>
|
/// 查找矩形
|
/// </summary>
|
/// <param name="image"></param>
|
/// <param name="color"></param>
|
/// <param name="minSize"></param>
|
/// <param name="maxRadius"></param>
|
/// <param name="rectangle"></param>
|
/// <returns></returns>
|
public static bool FindRectangle(out ZTRectangle rectangle,Image<Rgb,byte> image, ZTSize minSize, Int32 maxRadius, ZTColor color)
|
{
|
ZTRectangle limitRect = new ZTRectangle(0, 0, image.Width - 1, image.Height - 1);
|
return FindRectangle(out rectangle, image, minSize, maxRadius, limitRect, color);
|
}
|
|
/// <summary>
|
/// 查找矩形
|
/// </summary>
|
/// <param name="image">图像</param>
|
/// <param name="color">颜色</param>
|
/// <param name="minSize">最小的宽高</param>
|
/// <param name="maxRadius">转角最大半径</param>
|
/// <param name="rectangle">返回找到的矩形</param>
|
/// <param name="limitRect">在限制的区域里查找</param>
|
/// <returns></returns>
|
public static bool FindRectangle(out ZTRectangle rectangle, Image<Rgb, byte> image, ZTSize minSize, Int32 maxRadius, ZTRectangle limitRect, ZTColor color)
|
{
|
rectangle = default(ZTRectangle);
|
ZTLine topLine = ZTLine.Empty;
|
ZTLine top = default(ZTLine);
|
|
//查找顶部线
|
ZTRectangle limit = limitRect;
|
if (!FindLine(out top, image, minSize.Width, limit,Orientation.Horizontal, color))
|
{
|
return false;
|
}
|
|
//查找左边线
|
ZTLine left = default(ZTLine);
|
limit = new ZTRectangle(
|
Math.Max(limitRect.Start.X, top.X - maxRadius),
|
top.Y,
|
top.X+top.Length-minSize.Width,
|
limitRect.End.Y
|
);
|
if (!FindLine(out left, image, minSize.Height, limit,Orientation.Vertical, color))
|
{
|
return false;
|
}
|
|
|
//查找右边线
|
ZTLine right = default(ZTLine);
|
limit = new ZTRectangle(
|
top.X +minSize.Width,
|
top.Y,
|
Math.Min(limitRect.End.X, top.X + top.Length + maxRadius),
|
limitRect.End.Y
|
);
|
if (!FindLine(out right, image, minSize.Height, limit,Orientation.Vertical, color))
|
{
|
return false;
|
}
|
|
if (left.Length != right.Length)
|
{
|
return false;
|
}
|
|
//查找下边线
|
ZTLine down = default(ZTLine);
|
limit = new ZTRectangle(
|
left.X,
|
top.Y+minSize.Height,
|
right.X,
|
Math.Min(limitRect.End.Y, right.Y + right.Length + maxRadius)
|
);
|
if (!FindLine(out down, image, minSize.Width, limit,Orientation.Horizontal, color))
|
{
|
return false;
|
}
|
|
if (top.Length != down.Length)
|
{
|
return false;
|
}
|
rectangle = new ZTRectangle(left.X, top.Y, right.X, down.Y);
|
return true;
|
}
|
|
#endregion
|
|
#region 查找方块
|
|
/// <summary>
|
/// 查找方块
|
/// </summary>
|
/// <param name="image"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <param name="size"></param>
|
/// <param name="limitRectangle"></param>
|
/// <returns></returns>
|
public static List<ZTRectangle> FindBlocks(Image<Hsv, byte> image, Hsv minColor, Hsv maxColor, ZTSize size)
|
{
|
List<ZTRectangle> rects = new List<ZTRectangle>();
|
Image<Gray, byte> main = image.InRange(minColor, maxColor);
|
|
//腐蚀
|
//Mat element1 = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new System.Drawing.Size(3, 3), new System.Drawing.Point(0, 0));
|
//CvInvoke.Erode(main, main, element1, new System.Drawing.Point(-1, -1), 1, BorderType.Default, new MCvScalar(100));
|
|
//查找边框
|
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
|
Image<Gray, byte> hierarchy = new Image<Gray, byte>(main.Size);
|
CvInvoke.FindContours(main, contours, hierarchy, RetrType.External, ChainApproxMethod.ChainApproxSimple);
|
|
for (int i = 0; i < contours.Size; i++)
|
{
|
System.Drawing.Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
|
if (rect.Width < size.Width || rect.Height < size.Height)
|
{
|
continue;
|
}
|
ZTRectangle zrect = new ZTRectangle(rect.X, rect.Y, rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
|
rects.Add(zrect);
|
}
|
|
return rects;
|
}
|
#endregion
|
|
#region 查找数组
|
/// <summary>
|
/// 查找图像的二值化颜色数组
|
/// </summary>
|
/// <param name="position"></param>
|
/// <param name="source"></param>
|
/// <param name="colorArray"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="xSkip"></param>
|
/// <param name="ySkip"></param>
|
/// <returns></returns>
|
public static bool FindColorArrayForThreshold(out ZTRectangle position, Image<Rgb, byte> source, ColorArray colorArray, ZTRectangle limitRectangle, Int32 xSkip = 1, Int32 ySkip = 1)
|
{
|
Image<Rgb, byte> image = source;
|
|
using (var temp = source.Convert<Gray, byte>())
|
{
|
image = temp.ThresholdBinary(new Gray(colorArray.ThresholdValue), new Gray(255)).Convert<Rgb, byte>();
|
}
|
|
return FindColorArray(out position, image, colorArray, limitRectangle, xSkip, ySkip);
|
}
|
|
/// <summary>
|
/// 查找图像的灰度化颜色数组
|
/// </summary>
|
/// <param name="position"></param>
|
/// <param name="source"></param>
|
/// <param name="colorArray"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="xSkip"></param>
|
/// <param name="ySkip"></param>
|
/// <returns></returns>
|
public static bool FindColorArrayForGray(out ZTRectangle position, Image<Rgb, byte> source, ColorArray colorArray, ZTRectangle limitRectangle, Int32 xSkip = 1, Int32 ySkip = 1)
|
{
|
Image<Rgb, byte> image = source.Convert<Gray, byte>().Convert<Rgb,byte>();
|
|
return FindColorArray(out position, image, colorArray, limitRectangle, xSkip, ySkip);
|
}
|
|
|
/// <summary>
|
/// 查找颜色数组
|
/// </summary>
|
/// <param name="position"></param>
|
/// <param name="image"></param>
|
/// <param name="colorArray"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="xSkip"></param>
|
/// <param name="ySkip"></param>
|
/// <returns></returns>
|
public static bool FindColorArray(out ZTRectangle position, Image<Rgb, byte> image, ColorArray colorArray, ZTRectangle limitRectangle, Int32 xSkip = 1, Int32 ySkip = 1)
|
{
|
position = ZTRectangle.Empty;
|
if (xSkip < 1 || ySkip < 1)
|
{
|
throw new ArgumentOutOfRangeException("skip不能小于1");
|
}
|
for (int y = limitRectangle.Start.Y; y <= limitRectangle.End.Y; y += ySkip)
|
{
|
//超出高度
|
if ((limitRectangle.End.Y - y + 1) < colorArray.Size.Height)
|
{
|
return false;
|
}
|
for (int x = limitRectangle.Start.X; x <= limitRectangle.End.X; x += xSkip)
|
{
|
//超出宽度
|
if ((limitRectangle.End.X - x + 1) < colorArray.Size.Width)
|
{
|
break;
|
}
|
|
if (colorArray.Compare(image.Data, x, y))
|
{
|
position = new ZTRectangle(x, y, x + colorArray.Size.Width - 1, y + colorArray.Size.Height - 1);
|
return true;
|
}
|
}
|
}
|
|
return false;
|
}
|
|
|
/// <summary>
|
/// 查找颜色数组
|
/// </summary>
|
/// <param name="position"></param>
|
/// <param name="image"></param>
|
/// <param name="colorArray"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="filter"></param>
|
/// <param name="xSkip"></param>
|
/// <param name="ySkip"></param>
|
/// <returns></returns>
|
public static bool FindColorArray(out ZTRectangle position, Image<Rgb, byte> image, ColorArray colorArray, ZTRectangle limitRectangle, Func<ZTRectangle, bool> filter, Int32 xSkip = 1, Int32 ySkip = 1)
|
{
|
position = ZTRectangle.Empty;
|
if (xSkip < 1 || ySkip < 1)
|
{
|
throw new ArgumentOutOfRangeException("skip不能小于1");
|
}
|
for (int y = limitRectangle.Start.Y; y <= limitRectangle.End.Y; y += ySkip)
|
{
|
//超出高度
|
if ((limitRectangle.End.Y - y + 1) < colorArray.Size.Height)
|
{
|
return false;
|
}
|
for (int x = limitRectangle.Start.X; x <= limitRectangle.End.X; x += xSkip)
|
{
|
//超出宽度
|
if ((limitRectangle.End.X - x + 1) < colorArray.Size.Width)
|
{
|
break;
|
}
|
|
if (colorArray.Compare(image.Data, x, y))
|
{
|
position = new ZTRectangle(x, y, x + colorArray.Size.Width - 1, y + colorArray.Size.Height - 1);
|
if (filter(position))
|
{
|
return true;
|
}
|
}
|
}
|
}
|
|
return false;
|
}
|
|
|
|
/// <summary>
|
/// 查找所有数组方框
|
/// </summary>
|
/// <param name="image"></param>
|
/// <param name="colorArray"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="xSkip"></param>
|
/// <param name="ySkip"></param>
|
/// <returns></returns>
|
public static List<ZTRectangle> FindColorArray(Image<Rgb, byte> image, ColorArray colorArray, ZTRectangle limitRectangle, Int32 xSkip = 1, Int32 ySkip = 1)
|
{
|
List<ZTRectangle> rects = new List<ZTRectangle>();
|
|
if (xSkip < 1 || ySkip < 1)
|
{
|
throw new ArgumentOutOfRangeException("skip不能小于1");
|
}
|
for (int y = limitRectangle.Start.Y; y <= limitRectangle.End.Y; y += ySkip)
|
{
|
//超出高度
|
if ((limitRectangle.End.Y - y + 1) < colorArray.Size.Height)
|
{
|
break;
|
}
|
for (int x = limitRectangle.Start.X; x <= limitRectangle.End.X; x += xSkip)
|
{
|
//超出宽度
|
if ((limitRectangle.End.X - x + 1) < colorArray.Size.Width)
|
{
|
break;
|
}
|
|
if (colorArray.Compare(image.Data, x, y))
|
{
|
rects.Add(new ZTRectangle(x, y, x + colorArray.Size.Width - 1, y + colorArray.Size.Height - 1));
|
}
|
}
|
}
|
|
return rects;
|
}
|
|
|
|
|
/// <summary>
|
/// 查找数组
|
/// </summary>
|
/// <param name="position"></param>
|
/// <param name="image"></param>
|
/// <param name="limitRectangle"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <param name="pointOfBlock">相对于要查找点的偏移</param>
|
/// <returns></returns>
|
public static bool FindColorBlock(out ZTPoint position, Image<Rgb, byte> image, ZTRectangle limitRectangle, ZTHsvFloatColor minColor,ZTHsvFloatColor maxColor,ZTPoint[] pointOfBlock)
|
{
|
position = ZTPoint.Empty;
|
byte[,,] data = image.Data;
|
for (int y = limitRectangle.Start.Y; y <= limitRectangle.End.Y; y += 1)
|
{
|
|
for (int x = limitRectangle.Start.X; x <= limitRectangle.End.X; x += 1)
|
{
|
if (InRange(data, x, y, minColor, maxColor, pointOfBlock))
|
{
|
position = new ZTPoint(x, y);
|
return true;
|
}
|
}
|
}
|
|
return false;
|
}
|
|
#endregion
|
|
#region 颜色比对
|
/// <summary>
|
/// 颜色对比
|
/// </summary>
|
/// <param name="colorData"></param>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="compareOriginal"></param>
|
/// <param name="color"></param>
|
/// <returns></returns>
|
public static bool IsColor(byte[,,] colorData, Int32 x, Int32 y, ZTColor color)
|
{
|
if (colorData[y, x, 0] == color.Red && colorData[y, x, 1] == color.Green && colorData[y, x, 2] == color.Blue)
|
{
|
return true;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 颜色比对,不包含x,y,仅比较indexs中的位置
|
/// </summary>
|
/// <param name="colorData"></param>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="color"></param>
|
/// <param name="indexs">基于x,y的偏移量</param>
|
/// <returns></returns>
|
public static bool IsColor(byte[,,] colorData, Int32 x, Int32 y, ZTColor color, ZTPoint[] indexs)
|
{
|
ZTPoint point = ZTPoint.Empty;
|
for (int i = 0; i < indexs.Length; i++)
|
{
|
point = indexs[i];
|
if (!IsColor(colorData, x + point.X, y + point.Y, color))
|
{
|
return false;
|
}
|
}
|
return true;
|
}
|
|
/// <summary>
|
/// 颜色比对
|
/// </summary>
|
/// <param name="colorData"></param>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <returns></returns>
|
public static bool InRange(byte[,,] colorData, Int32 x, Int32 y, ZTHsvFloatColor minColor, ZTHsvFloatColor maxColor)
|
{
|
byte r = colorData[y, x, 0];
|
byte g = colorData[y, x, 1];
|
byte b = colorData[y, x, 2];
|
float h, s, v;
|
ColorUtils.RGBtoHSV(r, g, b, out h, out s, out v);
|
if (h >= minColor.H && s >= minColor.S && v >= minColor.V &&
|
h <= maxColor.H && s <= maxColor.S && v <= maxColor.V)
|
{
|
return true;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 颜色比对,不包含x,y,仅比较indexs中的位置
|
/// </summary>
|
/// <param name="colorData"></param>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="minColor"></param>
|
/// <param name="maxColor"></param>
|
/// <param name="indexs">相对于x,y的便宜量</param>
|
/// <returns></returns>
|
public static bool InRange(byte[,,] colorData, Int32 x, Int32 y, ZTHsvFloatColor minColor, ZTHsvFloatColor maxColor,ZTPoint[] indexs)
|
{
|
ZTPoint point = ZTPoint.Empty;
|
for (int i = 0; i < indexs.Length; i++)
|
{
|
point = indexs[i];
|
if (!InRange(colorData, x + point.X, y + point.Y, minColor,maxColor))
|
{
|
return false;
|
}
|
}
|
return true;
|
}
|
|
/// <summary>
|
/// 对比位置的颜色
|
/// </summary>
|
/// <param name="image"></param>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="colors"></param>
|
/// <returns></returns>
|
private static bool CompareColors(byte[,,] colorData, Int32 x, Int32 y, Orientation compareOriginal, ZTColor[] colors)
|
{
|
if (colors.Length <= 0)
|
{
|
return false;
|
}
|
if (colors.Length == 1)
|
{
|
return IsColor(colorData, x, y, colors[0]);
|
}
|
|
Int32 tx = x;
|
Int32 ty = y;
|
for (int i = 0; i < colors.Length; i++)
|
{
|
if (compareOriginal == Orientation.Horizontal)
|
{
|
tx = x + i;
|
}
|
else
|
{
|
ty = y + i;
|
}
|
if (!IsColor(colorData, tx, ty, colors[i]))
|
{
|
return false;
|
}
|
}
|
return true;
|
}
|
#endregion
|
|
|
|
/// <summary>
|
/// 是否在指定颜色在区域内
|
/// </summary>
|
/// <returns></returns>
|
public static bool RectExistsArray(ZTRectangle rect,ColorArray colorArray)
|
{
|
ZTRectangle colorRect = ZTRectangle.Empty;
|
return RectExistsArray(out colorRect, rect, colorArray);
|
}
|
|
|
|
/// <summary>
|
/// 是否在指定颜色在区域内
|
/// </summary>
|
/// <returns></returns>
|
public static bool RectExistsArray(out ZTRectangle arrayRect,ZTRectangle rect, ColorArray colorArray)
|
{
|
|
//截图
|
System.Drawing.Bitmap bitmap = ScreenCapture.Instance.CaptureScreen();
|
Image<Rgb, byte> image = new Image<Rgb, byte>(bitmap);
|
|
//查找地图右上边是否存在时空之门文字
|
if (CVHelper.FindColorArray(out arrayRect, image, colorArray, rect))
|
{
|
return true;
|
}
|
return false;
|
}
|
|
|
}
|
}
|