asmrobot
2019-11-13 576b92fd82f568572bc4beb125fa0ba0191a602f
src/RichCreator.Utility/CV/DnfCVHelper.cs
@@ -441,11 +441,11 @@
            if (rects.Count <= 0)
            {
                return Structs.ZTPoint.Empty;
                return ZTPoint.Empty;
            }
            //主角位置
            Structs.ZTPoint rolePosition = gameRect.Start + new Structs.ZTPoint(rects[0].Start.X + rolePositionOffset.Width, rects[0].Start.Y + rolePositionOffset.Height);
            ZTPoint rolePosition = gameRect.Start.Add(rects[0].Start.X + rolePositionOffset.Width, rects[0].Start.Y + rolePositionOffset.Height);
            return rolePosition;
        }
@@ -536,7 +536,7 @@
        }
        #region Location Point 1
        private static readonly Hsv LocationPointMinHsv = new Hsv(0, 0, 0);
        private static readonly Hsv LocationPointMaxHsv = new Hsv(0, 0, 5);
        private static readonly ZTSize LocationPointMinLimitSize = new ZTSize(33, 33);
@@ -690,5 +690,348 @@
            return true;
        }
        #endregion
        #region Location Point 2
        private static ColorArray LocationPoint = ColorArray.FromColorString(0, 0, "800,352,0,0,0$791,343,255,255,255$793,343,0,0,0$796,343,255,255,255$798,343,0,0,0$801,343,255,255,255$802,345,0,0,0$802,347,255,255,255$802,349,0,0,0$802,352,255,255,255$797,352,255,255,255$795,352,0,0,0$791,352,255,255,255$791,350,0,0,0$791,348,255,255,255$791,346,0,0,0$796,347,255,255,255$797,348,255,255,255");
        /// <summary>
        /// 获取定位点
        /// </summary>
        /// <param name="image"></param>
        /// <param name="gameRect"></param>
        /// <returns></returns>
        public static ParametersPoint GetLocationPoint(Image<Rgb,byte> image,ZTRectangle gameRect)
        {
            ZTRectangle rect = ZTRectangle.Empty;
            if (CVHelper.FindColorArray(out rect, image, LocationPoint, gameRect))
            {
                //获取定位标记,解析参数
                byte number = 0;
                bool bitValue = true;
                Int32 x = 0, y = 0;
                for (int bitIndex = 0; bitIndex <= 7; bitIndex++)
                {
                    //获取图像中存值的坐标
                    GetBitCoordinate(out x, out y, bitIndex);
                    //解析并设置值
                    if (!ParseBit(out bitValue, image, rect.Start.Add(x, y)))
                    {
                        return ParametersPoint.Empty;
                    }
                    else
                    {
                        number=SetBit(number, bitIndex, bitValue);
                    }
                }
                return new ParametersPoint(rect.GetCenterPoint(), number);
            }
            return ParametersPoint.Empty;
        }
        /// <summary>
        /// 设置指定位
        /// </summary>
        /// <param name="number"></param>
        /// <param name="bitIndex"></param>
        /// <param name="bitValue"></param>
        /// <returns></returns>
        private static byte SetBit(byte number, Int32 bitIndex,bool bitValue)
        {
            byte twonumber = 0;
            switch (bitIndex)
            {
                case 0:
                    if (bitValue)
                    {
                        twonumber = 0b00000001;
                    }
                    else
                    {
                        twonumber = 0b11111110;
                    }
                    break;
                case 1:
                    if (bitValue)
                    {
                        twonumber = 0b00000010;
                    }
                    else
                    {
                        twonumber = 0b11111101;
                    }
                    break;
                case 2:
                    if (bitValue)
                    {
                        twonumber = 0b00000100;
                    }
                    else
                    {
                        twonumber = 0b11111011;
                    }
                    break;
                case 3:
                    if (bitValue)
                    {
                        twonumber = 0b00001000;
                    }
                    else
                    {
                        twonumber = 0b11110111;
                    }
                    break;
                case 4:
                    if (bitValue)
                    {
                        twonumber = 0b00010000;
                    }
                    else
                    {
                        twonumber = 0b11101111;
                    }
                    break;
                case 5:
                    if (bitValue)
                    {
                        twonumber = 0b00100000;
                    }
                    else
                    {
                        twonumber = 0b11011111;
                    }
                    break;
                case 6:
                    if (bitValue)
                    {
                        twonumber = 0b01000000;
                    }
                    else
                    {
                        twonumber = 0b10111111;
                    }
                    break;
                case 7:
                    if (bitValue)
                    {
                        twonumber = 0b10000000;
                    }
                    else
                    {
                        twonumber = 0b01111111;
                    }
                    break;
            }
            if (bitValue)
            {
                return (byte)(number | twonumber);
            }
            else
            {
                return (byte)(number & twonumber);
            }
        }
        /// <summary>
        /// 得到指定位坐标
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="bitIndex"></param>
        private static void GetBitCoordinate(out Int32 x, out Int32 y, Int32 bitIndex)
        {
            x = 0;
            y = 0;
            switch (bitIndex)
            {
                case 0:
                    x = 8;
                    y = 6;
                    break;
                case 1:
                    x = 6;
                    y = 6;
                    break;
                case 2:
                    x = 4;
                    y = 6;
                    break;
                case 3:
                    x = 2;
                    y = 6;
                    break;
                case 4:
                    x = 8;
                    y = 2;
                    break;
                case 5:
                    x = 6;
                    y = 2;
                    break;
                case 6:
                    x = 4;
                    y = 2;
                    break;
                case 7:
                    x = 2;
                    y = 2;
                    break;
            }
        }
        /// <summary>
        /// 解析位状态
        /// true:1
        /// false:0
        /// </summary>
        /// <param name="bit"></param>
        /// <param name="image"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns>true:解析成功,false:解析失败</returns>
        private static bool ParseBit(out bool bit,Image<Rgb, byte> image, ZTPoint point)
        {
            bit = true;
            if (image.Data[point.Y, point.X, 0] == 0xff && image.Data[point.Y, point.X, 1] == 0xff && image.Data[point.Y, point.X, 2] == 0xff&&
                image.Data[point.Y, point.X+1, 0] == 0xff && image.Data[point.Y, point.X+1, 1] == 0xff && image.Data[point.Y, point.X+1, 2] == 0xff&&
                image.Data[point.Y+1, point.X, 0] == 0xff && image.Data[point.Y+1, point.X, 1] == 0xff && image.Data[point.Y+1, point.X, 2] == 0xff&&
                image.Data[point.Y+1, point.X+1, 0] == 0xff && image.Data[point.Y+1, point.X+1, 1] == 0xff && image.Data[point.Y+1, point.X+1, 2] == 0xff)
            {
                //白
                bit = true;
                return true;
            }
            if (image.Data[point.Y, point.X, 0] == 0x00 && image.Data[point.Y, point.X, 1] == 0x00 && image.Data[point.Y, point.X, 2] == 0x00 &&
                image.Data[point.Y, point.X + 1, 0] == 0x00 && image.Data[point.Y, point.X + 1, 1] == 0x00 && image.Data[point.Y, point.X + 1, 2] == 0x00 &&
                image.Data[point.Y + 1, point.X, 0] == 0x00 && image.Data[point.Y + 1, point.X, 1] == 0x00 && image.Data[point.Y + 1, point.X, 2] == 0x00 &&
                image.Data[point.Y + 1, point.X + 1, 0] == 0x00 && image.Data[point.Y + 1, point.X + 1, 1] == 0x00 && image.Data[point.Y + 1, point.X + 1, 2] == 0x00)
            {
                //黑
                bit = false;
                return true;
            }
            return false;
        }
        #endregion
        #region minimap
        /// <summary>
        /// 小方格色块偏移
        /// </summary>
        private static ZTPoint[] colorOffset = new ZTPoint[] {
            new ZTPoint(2,14),
            new ZTPoint(2,15),
            new ZTPoint(15,14),
            new ZTPoint(15,15),
        };
        /// <summary>
        /// 已经走过的房间颜色(青色)
        /// </summary>
        private static ZTHsvFloatColor crossedColorMin = new ZTHsvFloatColor(0.498, 0.998, 0.998);
        private static ZTHsvFloatColor crossedColorMax = new ZTHsvFloatColor(0.502, 1, 1);
        /// <summary>
        /// 是否穿越过的房间(青色)
        /// </summary>
        /// <param name="image"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static bool IsCrossedHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y)
        {
            if (CVHelper.InRange(image.Data, x, y, crossedColorMin, crossedColorMax, colorOffset))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 当前房间颜色(蓝色)
        /// </summary>
        private static ZTHsvFloatColor currentHouseColorMin = new ZTHsvFloatColor(0.665f, 0.998, 0.998);
        private static ZTHsvFloatColor currentHouseColorMax = new ZTHsvFloatColor(0.669f, 1, 1);
        /// <summary>
        /// 是否当前房间(蓝色)
        /// </summary>
        /// <param name="image"></param>
        /// <param name="minMapStart"></param>
        /// <param name="houseIndex"></param>
        /// <returns></returns>
        public static bool IsCurrentHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y)
        {
            if (CVHelper.InRange(image.Data, x, y, currentHouseColorMin, currentHouseColorMax, colorOffset))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 下一房间颜色(绿色)
        /// </summary>
        private static ZTHsvFloatColor nextHouseColorMin = new ZTHsvFloatColor(0.298f, 0.998, 0.998);
        private static ZTHsvFloatColor nextHouseColorMax = new ZTHsvFloatColor(0.302, 1, 1);
        /// <summary>
        /// 是否下一房间,绿色
        /// </summary>
        /// <param name="image"></param>
        /// <param name="minMapStart"></param>
        /// <param name="houseIndex"></param>
        /// <returns></returns>
        public static bool IsNextHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y)
        {
            if (CVHelper.InRange(image.Data, x, y, nextHouseColorMin, nextHouseColorMax, colorOffset))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 最终房间颜色(红色1)
        /// </summary>
        private static ZTHsvFloatColor overHouse1ColorMin = new ZTHsvFloatColor(0, 0.998, 0.998);
        private static ZTHsvFloatColor overHouse1ColorMax = new ZTHsvFloatColor(0.002, 1, 1);
        /// <summary>
        /// 最终房间颜色(红色2)
        /// </summary>
        private static ZTHsvFloatColor overHouse2ColorMin = new ZTHsvFloatColor(0.998, 0.998, 0.998);
        private static ZTHsvFloatColor overHouse2ColorMax = new ZTHsvFloatColor(1.0f, 1, 1);
        /// <summary>
        /// 是否最终房间
        /// </summary>
        /// <param name="image"></param>
        /// <param name="minMapStart"></param>
        /// <param name="houseIndex"></param>
        /// <returns></returns>
        public static bool IsOverHouseColor(Image<Rgb, byte> image, Int32 x, Int32 y)
        {
            if (CVHelper.InRange(image.Data, x, y, overHouse1ColorMin, overHouse1ColorMax, colorOffset)
                || CVHelper.InRange(image.Data, x, y, overHouse2ColorMin, overHouse2ColorMax, colorOffset))
            {
                return true;
            }
            return false;
        }
        #endregion
    }
}