(四)用swift4写iOS微信跳一跳的自动跳(开挂)程序——分析图像,找到关键点

如果想让跳一跳自动跳的话,那么最重要的就是要通过图像的分析,找到下一个台子的中心点以及当前时刻小人的脚的坐标,楼主自己想了一个算法,也算能够勉强识别这两个关键点了,但是不是图像识别的算法,所以容易收到图像噪声的干扰,稳定性不大高。。但是总算是能够实现自动跳的。。

下面分别讲一下识别这两个点的思路以及相应的代码。

(1)识别下一个台子的中心:先把图像转换成灰度图,然后得到差分图像,背景这种颜色均一的部分通常在差分图像中亮度值直接为0了,所以只需要自上而下进行光栅扫描,碰到第一个非零点,定义为台子的最高点(这个针对方形和圆形的台子都适用),将台子最高点的横坐标作为中心点的横坐标,然后这个最高点继续往下,找到台子的最宽水平面(通过颜色判断),定义为中心点的纵坐标。

代码:

//分析图像集,从时域和空域一起得到下一个块的中心点

    func getMidPoint(imageSet: [UIImage]) -> (Int, Int) {

        var point = (0, 0)

        let width = Int(imageSet[0].size.width)

        let height = Int(imageSet[1].size.height)

        let mImageOne = self.getGrayImage(sourceImage: imageSet[0])

        let mImageTwo = self.getGrayImage(sourceImage: imageSet[1])

        //将image2转换为二维矩阵,下面data2为这二维矩阵的指针

        let CGImageTwo = mImageTwo.cgImage

        let pPixelDataTwo = CGImageTwo?.dataProvider?.data

        let pData2: UnsafePointer<UInt8> = CFDataGetBytePtr(pPixelDataTwo)

        //将image1转换为二维矩阵,下面data1为这二维矩阵的指针

        let CGImageOne = mImageOne.cgImage

        let pPixelDataOne = CGImageOne?.dataProvider?.data

        let pData1: UnsafePointer<UInt8> = CFDataGetBytePtr(pPixelDataOne)

        //得到差值图像

        let num = width*height

        var diffImageArray: [Int16] = []

        var diffRect = [[Int16]]()

        for y in 0..<height {

            var tmp: [Int16] = []

            for x in 1..<width {

                let pos = y * width + x

                let pix = Int16(pData2[pos]) - Int16(pData2[pos-1])

                tmp.append(pix)

            }

            tmp.append(0)

            diffRect.append(tmp)

        }//2D

        //find the toppest point of the new block

        let initial_height = 400 //上方是分数等控件,不需要搜索

        let searchwindow_height = 200

        var findTopPoint: Bool = false

        var topPointX: Int = 0

        var topPointY: Int = 0

        let sigma = 0 //允许误差

        let (er,eg,eb) = self.getPixelColor(pos: CGPoint.init(x: 0, y: initial_height), image: imageSet[1]) //background color

        var diff: [Double] = []

        var count_all: [Int] = []

        for y in initial_height...(initial_height+searchwindow_height) {

            var count = 0

            var difftmp: Int32 = 0

            for x in 0..<width {

                if diffRect[y][x] > sigma {

                    count = count + 1

                    let (r,g,b) = self.getPixelColor(pos: CGPoint.init(x: x, y: y), image: imageSet[1])

                    difftmp = (abs(Int32(r)-Int32(er)) + abs(Int32(g)-Int32(eg)) + abs(Int32(b)-Int32(eb)))

                    if difftmp > 10 {

                        findTopPoint = true

                        topPointX = x

                        topPointY = y

                        break

                    }

                }

            }

            if findTopPoint {

                break

            }

        }

        //find the mid point

        var best_obj_width = 0

        var bestY = 0

        var bestX = 0

        let searchMid_height = 100

        for y in (topPointY+1)...(topPointY+searchMid_height) {

            let range = min(topPointX-1, width-topPointX-1)

            var obj_width = 0

            if diffRect[y][topPointX] <= sigma && diffRect[y][topPointX] >= 0 {

                for i in 0...range {

                    if diffRect[y][topPointX+i] <= sigma && diffRect[y][topPointX+i] >= 0 && diffRect[y][topPointX-i] >= 0 && diffRect[y][topPointX-i] <= sigma {

                        obj_width = obj_width + 1

                    } else {

                        break

                    }

                }

                if obj_width > best_obj_width && obj_width != range {

                    best_obj_width = obj_width

                    bestY = y

                    bestX = topPointX

                }

            }

            else {

                continue

            }

        }

        point = (bestX, bestY)

        print("point:\(point)")

        return point

    }


(2)找到小人脚的坐标

扫描相应的游戏区域,通过亮度值识别小人的坐标

代码:

func getGuyPoint(image: [[UInt8]], width: CGFloat, height: CGFloat, midX: Int, midY: Int) -> (Int, Int) {

        let bandwidth = Int(width) - 40 - midX

        let search_height = 300


        var bestMAD: Int32 = 1073741823

        var bestPosX = 0

        var bestPosY = 0

        var isFound : Bool = false

        for y in (midY-100)...(midY+search_height) {

            var left = midX > Int(width / 2) ? 0 : midX

            var right = midX > Int(width / 2) ? midX : Int(width) - 40

            let tmp = image[midX][midY]

            for x in left..<right {

                

                if image[y][x] <= 65 && image[y][x] < tmp && image[y + 112][x] <= 65 && image[y + 112][x] <= tmp{

                    bestPosY = y

                    bestPosX = x

                    isFound = true

                    break

                }

            }

            if isFound {

                break

            }

        }

        return (bestPosX, bestPosY + 125)

    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值