Ejemplo n.º 1
0
def getLittleWhitePointCenter(img, offset=(0,0), debug=False):
    '''
        找到下一跳的中心白点
    '''
    lowerb = (245, 245, 245)
    upperb = (245, 245, 245)
    
    
    mask = cv2.inRange(img, lowerb, upperb)
    image, contours, hierarchy = cv2.findContours(image=mask, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
    contours = vutils.contours_filter(contours, minWidth=35, maxWidth=45, minHeight=20, maxHeight=30)
    
    if len(contours) != 1:
        return None
    
    
    (x, y, w, h) = cv2.boundingRect(contours[0])
    cx = int(x+w/2+offset[0])
    cy = int(y+h/2+offset[1])

    if debug == False:
        return (cx, cy)
    else:
        canvas = img.copy()
        print("w: {}, h: {}".format(w, h))
        cv2.rectangle(canvas, (x,y), (x+w, y+h), (0,0,255), thickness=4)
        return (cx, cy), canvas
Ejemplo n.º 2
0
def getChessFootByColor(img):
    '''
        利用颜色检索棋子位置
    '''
    MIN_CHESS_WIDTH = 65
    MAX_CHESS_WIDTH = 80

    MIN_CHESS_HEIGHT = 200
    MAX_CHESS_HEIGHT = 230

    chess_mask = getChessFootMask(img)
    image, contours, hier = cv2.findContours(chess_mask, cv2.RETR_TREE,
                                             cv2.CHAIN_APPROX_SIMPLE)

    contours = vutils.contours_filter(contours,
                                      minHeight=MIN_CHESS_HEIGHT,
                                      maxHeight=MAX_CHESS_HEIGHT,
                                      minWidth=MIN_CHESS_WIDTH,
                                      maxWidth=MAX_CHESS_WIDTH)

    if len(contours) == 1:
        # 刚好匹配到目标棋子
        (x, y, w, h) = cv2.boundingRect(contours[0])
        # 返回棋子坐标
        return (int(x + w / 2), int(y + h))
    else:
        return None
Ejemplo n.º 3
0
def getLittleWhitePointCenter(img, offset=(0,0), debug=False):
    '''
        找到下一跳的中心白点
    '''
    lowerb = (245, 245, 245)
    upperb = (245, 245, 245)
    
    
    mask = cv2.inRange(img, lowerb, upperb)
    image, contours, hierarchy = cv2.findContours(image=mask, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
    contours = vutils.contours_filter(contours, minWidth=35, maxWidth=45, minHeight=20, maxHeight=30)
    
    if len(contours) != 1:
        if debug:
            # 没有发现小白块 或者发现了多个
            return (None, np.hstack((img, cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR))))
        return None
    
    # 确定白点的中心点
    (x, y, w, h) = cv2.boundingRect(contours[0])
    cx = int(x+w/2+offset[0])
    cy = int(y+h/2+offset[1])

    if debug == False:
        return (cx, cy)
    else:
        canvas = img.copy()
        cv2.rectangle(canvas, (x,y), (x+w, y+h), (0,0,255), thickness=4)
        return (cx, cy), canvas
Ejemplo n.º 4
0
def getChessFootPosi(img):
    MIN_CHESS_WIDTH = 65
    MAX_CHESS_WIDTH = 80

    MIN_CHESS_HEIGHT = 200
    MAX_CHESS_HEIGHT = 230

    chess_mask = getChessBinImg(img)
    image, contours, hier = cv2.findContours(chess_mask, cv2.RETR_TREE,
                                             cv2.CHAIN_APPROX_SIMPLE)
    contours = vutils.contours_filter(contours,
                                      minHeight=MIN_CHESS_HEIGHT,
                                      maxHeight=MAX_CHESS_HEIGHT,
                                      minWidth=MIN_CHESS_WIDTH,
                                      maxWidth=MAX_CHESS_WIDTH)
    rects = []
    for c in contours:
        (x, y, w, h) = cv2.boundingRect(c)

        rects.append((x, y, w, h))

    return rects, contours
Ejemplo n.º 5
0
    def cal_top_box_center(self):
        '''
            获取最顶层盒子的中心
        '''

        canvas = np.copy(self.img)

        image, contours, hier = cv2.findContours(self.box_mask, cv2.RETR_TREE,
                                                 cv2.CHAIN_APPROX_SIMPLE)

        contours = vutils.contours_filter(contours, minHeight=50, minWidth=50)

        boxes = []

        for c in contours:
            x, y, w, h = cv2.boundingRect(c)
            boxes.append((x, y, w, h))

        top_box = boxes[0]
        top_contour = contours[0]

        for i in range(1, len(contours)):
            # 对比box的y坐标的值, 获取最小 也就是最靠上方的盒子
            box = boxes[i]
            if top_box[1] > box[1]:
                top_box = box
                top_contour = contours[i]

        # print("box : {}".format(top_box))

        (x, y, w, h) = top_box

        # 这里有个问题, 如果两个box离的很近
        # 当前的盒子跟下一跳的盒子的区域会联通, 所以需要裁减
        # 通过判断chess是否在box中, 来判断是否相邻的两个盒子被当成一个。
        if vutils.isPointInRectangle(top_box, self.chs_fposi):
            # 检测到盒子连体, 采用备用方案, 获取下一个盒子的中心。

            miny = 100000
            ptop = None
            for points in top_contour:
                (px, py) = points[0]
                if py < miny:
                    miny = py
                    ptop = (px, py)
            # 把最顶上的坐标中x点作为box中心点。
            cx = ptop[0]
            dh = int(abs(cx - self.chs_fposi[0]) / math.sqrt(3))
            cy = self.chs_fposi[1] - dh

            radius = abs(cy - ptop[1])

            (x, y, w, h) = (cx - radius, ptop[1], 2 * radius, 2 * radius)

            # 再次判断chess底部是否落在矩形区域内
            # 进行对应的放缩
            # 下面的这段代码纯属靠凡哥发挥 实验有效。
            if vutils.isPointInRectangle((x, y, w, h), self.chs_fposi):
                # 这里移动值, 我选的是chess矩形区域的宽度
                delta = self.chs_rect[2]
                if self.chs_fposi[0] < x:
                    x -= delta
                else:
                    x += delta
                w -= delta
                h -= delta
            self.nbox_rect = (x, y, w, h)

            # 重新调整中心
            self.nbox_center = (int(x + w / 2), int(y + h / 3))

        else:
            self.nbox_rect = (x, y, w, h)
            (x, y, w, h) = self.nbox_rect
            # 计算中心点, 立体盒子的高的1/3处大概就是中心点y坐标的位置
            # 中心点的x左边标定为宽度的1/2处.
            self.nbox_center = (int(x + w / 2), int(y + h / 3))
        (x22, y22, w22, h22) = self.nbox_rect
        x33, y33 = self.chs_fposi
        x44, y44 = self.nbox_center
        cv2.rectangle(canvas, (x22, y22), (x22 + w22, y22 + h22), (255, 0, 0),
                      5)
        cv2.circle(canvas, (x33, y33), 5, (0, 0, 255), -1)
        cv2.circle(canvas, (x44, y44), 5, (0, 0, 255), -1)
        cv2.imshow('canvas', canvas)
Ejemplo n.º 6
0
def getNextJumpPlatCenter(img, debug=False):
    '''
        获取下一跳平台的中心
    '''
    # 声明画布
    canvas = img.copy()

    edge = getCannyEdge(img)
    # 获取边缘信息
    image, contours, hierarchy = cv2.findContours(image=edge, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
    contours = vutils.contours_filter(contours, minWidth=10, minHeight=10)
    
    # 找到最大
    next_box_cnt = min(contours, key=lambda cnt: tuple(cnt[cnt[:,:,1].argmin()][0])[1])
    
    # 顶点序号
    top_point_idx = next_box_cnt[:,:,1].argmin()
    # 顶点
    top_point = tuple(next_box_cnt[top_point_idx,0,:2])
    
    # 背景色取样
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    refer_back_color = img_hsv[top_point[1], top_point[0]]

    left_idx_itr = 1
    right_idx_itr = -1
    if next_box_cnt[top_point_idx+left_idx_itr,0, 0] > top_point[0]:
        left_idx_itr, right_idx_itr = right_idx_itr, left_idx_itr 

    right_pt_idx = top_point_idx+right_idx_itr
    left_pt_idx = top_point_idx+left_idx_itr

    right_point = None
    left_point = None

    # 寻找右边的边缘点
    while True:
        # 当前right point
        right_point = tuple(next_box_cnt[right_pt_idx,0,:2])
        next = tuple(next_box_cnt[right_pt_idx+right_idx_itr,0,:2])
        
        if not isNextPoint(right_point, next, x_direction=1):
            break
        elif isInShadow(refer_back_color, img_hsv[next[1]+5, next[0]]):
            # 判断边缘下方的五个像素是不是阴影
            break
        
        right_pt_idx += right_idx_itr
    
    # 寻找左边的边缘点
    while True:
        left_point = tuple(next_box_cnt[left_pt_idx,0,:2])
        next = tuple(next_box_cnt[left_pt_idx+left_idx_itr,0,:2])

        if not isNextPoint(left_point, next, x_direction=-1):
            break
        elif isInShadow(refer_back_color, img_hsv[next[1]+5, next[0]]):
            break

        left_pt_idx += left_idx_itr
    # 调整三个点的位置
    (top_point, left_point, right_point) = adjust_points(top_point, left_point, right_point)
    down_point = (left_point[0]+right_point[0]-top_point[0],left_point[1]+right_point[1]-top_point[1])

    # 生成下一跳平台的搜索区域
    # TODO 检索椭圆形 四边形
    contour = np.array([
        [list(top_point)],
        [list(right_point)],
        [list(down_point)],
        [list(left_point)]])

    (x, y, w, h) = cv2.boundingRect(contour)
    # 在矩形区域内检索小白点提示
    res_pt = getLittleWhitePointCenter(img[y:y+h, x:x+w], offset=(x,y))
    
    center_point = None
    if res_pt is not None:
        # print("find white point")
        # print(res_pt)
        center_point = res_pt
    else:
        # 取left_point与right_point 中间处作为中心点
        cx = int((left_point[0]+right_point[0])/2)
        cy = int((left_point[1]+right_point[1])/2)
        center_point = (cx, cy)

    if debug == True:
        cv2.drawContours(image=canvas, contours=[next_box_cnt], contourIdx=-1, color=(125,125,125), thickness=1)
        canvas[top_point[1],top_point[0]] = [0,0,255]

        canvas[left_point[1],left_point[0]] = [0, 255, 0]
        canvas[right_point[1], right_point[0]] = [255, 0, 0]

        next_right = tuple(next_box_cnt[right_pt_idx+right_idx_itr,0,:2])
        canvas[next_right[1], next_right[0]] = [0,0,0]
        next_left = tuple(next_box_cnt[left_pt_idx+left_idx_itr,0,:2])
        canvas[next_left[1], next_left[0]] = [0,0,0]

        print('LEFT: {}, TOP: {}, RIGHT: {}'.format(left_point, top_point, right_point))

    else:
        # 设定圆圈半径
        pt_radius = 10
        # 绘制轮廓
        cv2.drawContours(image=canvas, contours=[next_box_cnt], contourIdx=-1, color=(0,0,255), thickness=3)
        cv2.circle(canvas, top_point, pt_radius, (0, 255, 0), thickness=-1)
        cv2.circle(canvas, left_point, pt_radius, (0, 255, 255), thickness=-1)
        cv2.circle(canvas, right_point, pt_radius, (255, 0, 0), thickness=-1)
        cv2.circle(canvas, down_point, pt_radius, (255,255,0), thickness=-1)
        # 绘制检索框
        # x,y,w,h = next_plat_rect
        # cv2.rectangle(canvas, (x,y), (x+w, y+h), (255,255,255), thickness=2)
        cv2.circle(canvas, center_point, pt_radius, (45,100,255), thickness=-1)
    
    return center_point,canvas
Ejemplo n.º 7
0
def getNextJumpPlatCenter(img, debug=False):
    '''
        获取下一跳平台的中心
    '''
    # 声明画布
    canvas = img.copy()
    # 获取边缘图像
    edge = getCannyEdge(img)
    # 获取边缘信息
    image, contours, hierarchy = cv2.findContours(image=edge, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
    # 对轮廓点集进行过滤
    contours = vutils.contours_filter(contours, minWidth=50, minHeight=50)
    
    # 找到最高顶点所在轮廓
    next_box_cnt = min(contours, key=lambda cnt: tuple(cnt[cnt[:,:,1].argmin()][0])[1])
    
    # 获取顶点序号
    top_point_idx = next_box_cnt[:,:,1].argmin()
    # 顶点
    top_point = tuple(next_box_cnt[top_point_idx,0,:2])
    
    # 背景色取样
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    refer_back_color = img_hsv[top_point[1], top_point[0]]

    # 分别向左向右找到边界点
    left_idx_itr = 1
    right_idx_itr = -1
    # 校正方向对应的序号叠加
    if next_box_cnt[top_point_idx+left_idx_itr,0, 0] > top_point[0]:
        left_idx_itr, right_idx_itr = right_idx_itr, left_idx_itr 

    right_pt_idx = top_point_idx+right_idx_itr
    left_pt_idx = top_point_idx+left_idx_itr

    right_point = None
    left_point = None

    # 寻找右边的边缘点
    while True:
        # 当前right point
        right_point = tuple(next_box_cnt[right_pt_idx,0,:2])
        # 获取下一个右边的点
        next = tuple(next_box_cnt[right_pt_idx+right_idx_itr,0,:2])
        # 判断这个点是否可以延伸
        if not isNextPoint(right_point, next, x_direction=1):
            break
        elif isInShadow(refer_back_color, img_hsv[next[1]+5, next[0]]):
            # 判断边缘下方的五个像素是不是阴影
            break
        
        right_pt_idx += right_idx_itr
    
    # 寻找左边的边缘点
    while True:
        left_point = tuple(next_box_cnt[left_pt_idx,0,:2])
        next = tuple(next_box_cnt[left_pt_idx+left_idx_itr,0,:2])

        if not isNextPoint(left_point, next, x_direction=-1):
            break
        elif isInShadow(refer_back_color, img_hsv[next[1]+5, next[0]]):
            break

        left_pt_idx += left_idx_itr
    # 调整三个点的位置
    (top_point, left_point, right_point) = adjust_points(top_point, left_point, right_point)
    # 通过平行四边形的定理 获取下方的点
    down_point = (left_point[0]+right_point[0]-top_point[0],left_point[1]+right_point[1]-top_point[1])

    # 生成下一跳平台的搜索区域
    contour = np.array([
        [list(top_point)],
        [list(right_point)],
        [list(down_point)],
        [list(left_point)]])

    (x, y, w, h) = cv2.boundingRect(contour)
    # 在矩形区域内检索小白点提示
    res_pt = getLittleWhitePointCenter(img[y:y+h, x:x+w], offset=(x,y))
    
    center_point = None
    if res_pt is not None:
        # 如果存在小白点 就直接作为中心点
        center_point = res_pt
    else:
        # 取left_point与right_point 中间处作为中心点
        cx = int((left_point[0]+right_point[0])/2)
        cy = int((left_point[1]+right_point[1])/2)
        center_point = (cx, cy)
    
    # 设定圆圈半径
    pt_radius = 10
    # 绘制下一跳中心点
    cv2.circle(canvas, center_point, pt_radius, (45,100,255), thickness=-1)
    if debug == True:
        
        # 绘制轮廓
        cv2.drawContours(image=canvas, contours=[next_box_cnt], contourIdx=-1, color=(0,0,255), thickness=3)
        # 绘制平行四边形的四个点
        cv2.circle(canvas, top_point, pt_radius, (0, 255, 0), thickness=-1)
        cv2.circle(canvas, left_point, pt_radius, (0, 255, 255), thickness=-1)
        cv2.circle(canvas, right_point, pt_radius, (255, 0, 0), thickness=-1)
        cv2.circle(canvas, down_point, pt_radius, (255,255,0), thickness=-1)
        
    
    return center_point,canvas