从视觉到决策:基于OpenMV的三子棋AI系统全栈开发实战

Liunx搭建GitLab服务器后忘记登录密码的解决方法 提示:基于CentOS操作系统搭建的gitLab服务器。 阅读详情

1. 项目缘起:为什么选择OpenMV做三子棋AI?

大家好,我是老张,一个在嵌入式视觉和AI领域摸爬滚打了十多年的工程师。这些年我玩过不少开发板,从早期的树莓派到各种国产AIoT模组,但说到做快速原型验证,尤其是需要“眼睛”和“大脑”结合的小项目,我第一个想到的还是OpenMV。它就像是一个集成了摄像头的微型Python计算机,开箱即用,省去了大量驱动和底层配置的麻烦。

这次咱们要聊的,就是用OpenMV从头到尾搭建一个能“看见”棋盘、能“思考”策略、还能“动手”下棋的完整三子棋AI系统。听起来是不是挺酷?这可不是一个简单的图像识别demo,而是一个涵盖了机器视觉、AI决策算法、嵌入式系统控制、串口通信的全栈实战项目。你可能会问,三子棋规则这么简单,用OpenMV是不是有点“杀鸡用牛刀”?其实不然。这个项目麻雀虽小,五脏俱全,它完美地串联起了从物理世界感知到数字世界决策,再回到物理世界执行的全过程。你在这个过程中踩过的每一个坑,比如光照变化导致识别不稳、算法决策太慢、串口通信丢数据,都是未来做更复杂项目(比如自动驾驶小车、智能分拣机械臂)的宝贵经验。

我选择OpenMV,主要是看中它的三点:第一是开发效率极高,用Python写图像处理算法,比在单片机上用C折腾OpenCV快太多了;第二是生态友好,星瞳科技提供了非常完善的中文文档和社区支持,新手也能快速上路;第三是硬件接口丰富,自带UART、I2C、SPI,方便连接机械臂、舵机等执行机构。这个项目,咱们的目标不仅仅是让AI能下棋,更是要打造一个稳定、可交互、能应对真实环境挑战的自动化系统。我会把我实际开发中遇到的坑和解决方案都掰开揉碎了讲给你听,保证你跟着做一遍,就能掌握这套方法,应用到自己的创意项目里去。

2. 视觉系统的基石:稳定可靠的棋盘与棋子识别

视觉是整个系统的“眼睛”,眼睛要是看错了,后面的大脑和手全得抓瞎。所以,咱们的第一步,也是最重要的一步,就是让OpenMV在各种环境下都能稳稳地“看”清棋盘和棋子。

2.1 棋盘识别:一次校准,终身受用

原始文章里提到了一个非常聪明的思路:只在第一帧识别棋盘边框,之后就一直用这个边框坐标。这个思路我强烈赞同,并且在实际项目中验证了它的有效性。为什么这么做?因为反复识别矩形框(find_rects)是个计算量不小的操作,而且环境光线、摄像头角度稍有变化,就可能识别不到或者识别错,导致后续的格子划分全部乱套。

我的具体实现和优化是这样的:开机后,我会在镜头前放好棋盘,然后程序进入一个短暂的“校准模式”。在这个模式下,它会连续采集多帧(比如10帧),对每一帧识别到的最大矩形进行面积和长宽比筛选(确保是棋盘而不是别的什么矩形),然后把所有合格矩形的角点坐标求个平均值。这样做的好处是,能平滑掉单帧识别可能出现的微小抖动,得到一个更稳定、更准确的初始棋盘坐标。代码上,我定义了一个calibrate_board()函数来做这个事。

def calibrate_board(img, samples=10):
    """校准棋盘,采集多帧样本取平均角点"""
    corners_list = []
    for i in range(samples):
        rects = img.find_rects(threshold=15000) # 阈值可以调高,更严格
        if rects:
            # 找面积最大的矩形
            max_rect = max(rects, key=lambda r: r.w() * r.h())
            # 增加尺寸和长宽比约束,更精准
            if 80 < max_rect.w() < 120 and 80 < max_rect.h() < 120 and 0.8 < max_rect.w()/max_rect.h() < 1.2:
                corners_list.append(max_rect.corners())
        time.sleep_ms(50) # 稍作延时,采集不同时刻的图像
    if corners_list:
        # 将列表转换为numpy数组便于计算均值 (OpenMV IDE内置了micropython的ulab,类似numpy)
        import ulab as np
        corners_array = np.array(corners_list)
        avg_corners = np.mean(corners_array, axis=0)
        return avg_corners.tolist()
    return None

拿到这四个角点(corners)后,我就把它们存入全局变量。在后续的主循环里,再也不调用find_rects了,直接基于这个corners去划分九宫格。这就好比你在桌子上用胶带贴出了一个固定的棋盘区域,以后摄像头只管看这个区域里面的事,外面天塌了都跟它没关系,稳定性大大提升。

2.2 棋子检测:阈值调参与形态过滤的双重保险

棋盘固定了,接下来就是识别格子里的棋子是黑是白还是空。这里有两个关键:颜色阈值和形状筛选。

颜色阈值是老大难问题。原始文章给出的black_threshold和white_threshold是一个很好的起点,但你直接拿去用,很可能在你家的灯光下就失灵了。我的经验是,一定要用OpenMV IDE自带的“阈值编辑器”工具(Tools -> Threshold Editor)来现场调试。把棋盘和棋子放在你项目实际要用的光照环境下,用这个工具里的滑块调整LAB(或RGB)各个通道的范围,直到在预览图里,棋子区域被高亮选中,而棋盘背景是黑色。记住,阈值不是一成不变的,白天晚上、开灯关灯都可能需要微调。一个更鲁棒的办法是,采用动态阈值或多阈值融合。比如,可以同时检测“深色”和“浅色”两种阈值,或者根据棋盘格子的平均灰度值来微调黑白棋子的阈值范围。

形状筛选是避免误判的关键。find_blobs找到的是一堆色块,可能包括反光点、棋盘格子线的交叉点、甚至摄像头上的灰尘。所以我们必须通过blob的属性来过滤。对于棋子,我们预期它是一个近似圆形的、有一定面积的色块。

  • blob.pixels():像素数量,可以过滤掉太小的噪点。
  • blob.area():面积,确保棋子大小合理。
  • blob.roundness():圆度,接近1表示越圆。这是区分棋子和不规则反光斑点的利器。通常黑棋(实心圆)的圆度可以设高一点(如>0.8),白棋(可能因为反光边缘不那么完美)可以设低一点(如>0.4)。
# 在划分好的每个格子ROI内进行检测
blobs_black = img.find_blobs([black_threshold], roi=cell_roi, merge=True, margin=10)
blobs_white = img.find_blobs([white_threshold], roi=cell_roi, merge=True, margin=10)

valid_black = []
for b in blobs_black:
    # 综合面积、像素和圆度进行筛选
    if b.pixels() > 25 and b.area() > 60 and b.roundness() > 0.75:
        valid_black.append(b)

valid_white = []
for b in blobs_white:
    if b.pixels() > 20 and b.area() > 40 and b.roundness() > 0.35:
        valid_white.append(b)

这里有个我踩过的坑:merge参数和margin参数。merge=True会把相邻的、颜色相近的色块合并,这对于一个完整的棋子来说是好事。但margin(边界扩展)设置不当,可能会把两个靠得近的棋子错误地合并。我的建议是,在棋子摆放不重叠的前提下,可以设置一个较小的margin(比如5-10),或者干脆设为0,然后主要依靠后续的位置判断(一个格子只认一个棋子中心点)来去重。

2.3 状态跟踪与坐标映射:为AI构建数字棋盘

识别出棋子后,我们需要把视觉信息转化为AI能理解的数字信息——也就是那个3x3的二维数组board。这里涉及一个坐标映射的过程。我们的摄像头看到的是扭曲的透视图像,而AI思考的棋盘是逻辑上的3x3网格。

原始文章用插值法计算每个小格子的角点,这个方法非常经典。我在此基础上,增加了一步:计算每个格子的中心点坐标。这个中心点坐标有两个重要作用:第一,用于绘制格子编号,方便调试和观察;第二,也是更关键的,当AI决定下棋位置后,需要把这个逻辑位置(如第5格)转换成图像上的物理坐标(x, y),再通过坐标变换(如果用了机械臂,可能还需要手眼标定)告诉执行机构“把棋子放在这里”。

# 假设corners是之前校准保存的四个角点 [top-left, top-right, bottom-right, bottom-left]
def get_grid_center(corners, row, col):
    """根据棋盘角点和行列号,计算对应格子的中心图像坐标"""
    # 双线性插值
    row_factor = row / 3.0
    col_factor = col / 3.0
    top = (corners[0][0] * (1-col_factor) + corners[1][0] * col_factor,
           corners[0][1] * (1-col_factor) + corners[1][1] * col_factor)
    bottom = (corners[3][0] * (1-col_factor) + corners[2][0] * col_factor,
              corners[3][1] * (1-col_factor) + corners[2][1] * col_factor)
    center_x = top[0] * (1-row_factor) + bottom[0] * row_factor
    center_y = top[1] * (1-row_factor) + bottom[1] * row_factor
    return int(center_x), int(center_y)

每次循环,我们遍历9个格子,根据识别结果更新board数组:0为空,1为黑子(玩家),2为白子(AI)。同时,我们可以把黑子和白子的逻辑位置(行列)分别存储到black_positions和white_positions列表中,这个列表后面会直接用于胜负判断,比遍历二维数组更高效。

3. AI大脑:不止于随机,实现有策略的下棋逻辑

视觉部分把现实世界数字化了,接下来就是AI大脑的表演时间。原始文章里的AI逻辑非常简单:遍历棋盘,找到第一个空位就下下去。这确实是个能跑的AI,但毫无策略可言,相当于一个不会思考的婴儿。我们要做的,是给它注入一点“智慧”。

3.1 胜负判断算法:高效检查连线

在思考AI怎么下之前,得先教会它判断输赢。原始文章提供的check_continuous_line函数思路是对的,但实现上可以更简洁高效。三子棋的棋盘很小,我们完全可以用更直接的方式。我的做法是,利用之前准备好的black_positions和white_positions列表(里面是(row, col)元组)。

def check_winner(positions):
    """检查给定的棋子位置列表是否连成三子"""
    # 将位置列表转换为按行、列、对角线检查的集合
    rows = {}
    cols = {}
    for (r, c) in positions:
        rows[r] = rows.get(r, 0) + 1
        cols[c] = cols.get(c, 0) + 1
    # 检查是否有行或列满3个
    if 3 in rows.values() or 3 in cols.values():
        return True
    # 检查两条对角线
    diag1 = sum(1 for (r,c) in positions if r == c) # 主对角线
    diag2 = sum(1 for (r,c) in positions if r + c == 2) # 副对角线
    return diag1 == 3 or diag2 == 3

这个函数只针对某一方的棋子位置进行判断,在AI决策时会反复用到。它比遍历所有方向稍微快一点,代码也更易读。

3.2 决策算法:从“菜鸟”到“高手”的进阶

一个像样的三子棋AI,至少应该具备以下几个层次的决策能力,我称之为决策金字塔:

  1. 第一层(进攻):检查自己是否有一步制胜的机会。即遍历所有空位,如果AI(白子)下在那里能立刻连成三子,就下那里。
  2. 第二层(防守):检查对手是否有一步制胜的机会。即遍历所有空位,如果玩家(黑子)下在那里能立刻连成三子,就必须堵住那里。
  3. 第三层(创造机会):在既不能赢也不用堵的情况下,选择一个对自己最有利的位置。比如,下在能让自己同时产生两个“活二”(再下一子就能赢的线路)的位置,或者抢占中心、角落等战略要点。

我们可以用一个简单的优先级评分来实现这个逻辑:

def ai_move(board):
    """AI决策函数,返回最优的行列坐标"""
    # 优先级1: 自己能赢,马上赢
    for r in range(3):
        for c in range(3):
            if board[r][c] == 0:
                board[r][c] = 2 # 假设AI下这里
                if check_winner(get_positions(board, 2)): # 检查AI是否赢
                    board[r][c] = 0 # 恢复棋盘
                    return r, c
                board[r][c] = 0 # 恢复棋盘
    # 优先级2: 对手能赢,必须堵
    for r in range(3):
        for c in range(3):
            if board[r][c] == 0:
                board[r][c] = 1 # 假设玩家下这里
                if check_winner(get_positions(board, 1)): # 检查玩家是否赢
                    board[r][c] = 0
                    return r, c # AI下这里堵住
                board[r][c] = 0
    # 优先级3: 战略位置选择
    # 定义一个简单的位置价值表,中心最值钱,角落次之,边再次之
    position_score = [
        [3, 2, 3],
        [2, 4, 2],
        [3, 2, 3]
    ]
    best_score = -1
    best_move = None
    for r in range(3):
        for c in range(3):
            if board[r][c] == 0:
                # 可以在这里加入更复杂的评估,比如计算这个位置能形成多少条“活二”
                score = position_score[r][c]
                if score > best_score:
                    best_score = score
                    best_move = (r, c)
    return best_move # 返回价值最高的空位

这个AI虽然还远不及Minimax或Alpha-Beta剪枝等经典算法强大,但已经足够和普通人类玩家有来有回了。在OpenMV有限的算力下,实现这种启发式规则是性价比最高的选择。

4. 系统联调:串口通信与机械臂控制的实战要点

AI想好了下哪里,接下来就要通过串口告诉单片机,驱动机械臂去执行。这是从“数字世界”回到“物理世界”的关键一步,也是坑最多的地方。

4.1 设计一个可靠的通信协议

直接用uart.write(str(num))发送一个数字字符是最简单的,但在复杂的电磁环境下,很容易出错。我强烈建议设计一个简单的帧协议。一个经典的格式是:帧头 + 数据 + 校验和 + 帧尾。

例如,我们可以定义一帧数据为:0xAA(帧头) + 棋格编号(1-9) + 校验和(前面所有字节的和取低8位) + 0x55(帧尾)。

  • 帧头帧尾:用于在数据流中识别一帧数据的开始和结束。
  • 校验和:用于验证数据在传输过程中是否出错。单片机端收到后,会计算除帧头帧尾和校验和之外所有字节的和,与收到的校验和比对,不一致则丢弃这一帧,请求重发。

在OpenMV端,发送函数可以这样写:

def send_grid_number(num):
    """通过UART发送棋格编号,带简单协议"""
    data_byte = num & 0xFF # 确保是一个字节
    checksum = (0xAA + data_byte) & 0xFF
    frame = bytearray([0xAA, data_byte, checksum, 0x55])
    uart.write(frame)
    print("[UART Sent] Grid:", num, "Frame:", frame)

在单片机(如STM32、Arduino)端,你需要编写相应的解析程序,不断读取串口数据,寻找0xAA,然后读取后续字节,验证校验和与帧尾,最后提取出有效的棋格编号。

4.2 机械臂坐标映射与动作序列

单片机收到“下在第5格”的指令后,需要控制机械臂完成“移动到棋子堆 -> 夹取棋子 -> 移动到第5格中心 -> 放下棋子”这一系列动作。这里的关键在于坐标映射。

你需要事先进行手眼标定(虽然对于这个项目,一个简单的比例映射可能就够了)。简单来说,就是先在图像上点击第1格和第9格的中心点,同时记录下机械臂在这两个位置时的关节角度或坐标。这样就能建立一个从图像像素坐标到机械臂工作空间坐标的线性映射关系。当AI给出逻辑格子编号后,OpenMV可以将其转换为图像中心坐标,再通过这个映射关系计算出机械臂的目标坐标,发送给单片机。

更实际的步骤是:

  1. 预标定:在程序初始化时,手动引导机械臂走到棋盘区域的四个角点或几个特征点,记录下这些点的图像坐标和机械臂坐标。
  2. 坐标转换:在代码里,使用这些点对,通过透视变换或仿射变换计算出转换矩阵。这样,对于图像上任何一个点,都能算出机械臂应该去的位置。
  3. 动作队列:机械臂的每一个完整动作(如夹取、移动、放下)都应该分解为一系列基本指令(如各舵机角度),并考虑动作之间的延时,避免过快导致抖动或失步。

4.3 调试技巧与抗干扰设计

在实际联调中,我遇到了几个典型问题:

  • 问题一:串口数据丢失或错乱。解决方法:除了使用带校验的协议,还要在OpenMV端增加重发机制。如果一段时间内没收到单片机的应答(ACK),就重发上一次的指令。同时,适当降低波特率(如9600)往往比高波特率更稳定。
  • 问题二:机械臂动作不到位。解决方法:一是检查电源是否充足,动作瞬间电流不足会导致舵机抖动;二是在每个关键动作后,增加一个状态反馈环节。比如,机械臂移动到目标位置后,用一个简单的光电传感器或限位开关确认一下,再执行下一步。
  • 问题三:视觉与动作不同步。比如机械臂还没放下棋子,视觉系统就以为棋盘状态已经更新,导致AI基于错误棋盘思考。解决方法:引入状态机。系统可以有几个明确的状态:WAITING_FOR_PLAYER(等待玩家落子)、DETECTING(视觉检测)、AI_THINKING(AI决策)、ROBOT_MOVING(机械臂执行)、WAITING_CONFIRM(等待动作完成确认)。只有收到机械臂“动作完成”的反馈后,系统才从ROBOT_MOVING状态切回DETECTING状态,开始新一轮检测。

5. 性能优化与项目进阶思考

当你把整个系统跑通,看着机械臂和你对战三子棋时,成就感绝对是爆棚的。但这只是开始,我们可以从以下几个方面让这个项目变得更专业、更健壮。

5.1 OpenMV端的性能压榨

OpenMV的算力有限,尤其是在跑图像处理的同时还要进行AI决策和通信。我们可以做这些优化:

  • 降低分辨率:QQVGA (160x120) 对于这个项目已经足够,降低分辨率能大幅减少find_blobs等函数的处理时间。
  • 限制ROI:我们已经把视觉处理严格限制在棋盘区域内,这本身就是最大的优化。确保roi参数设置正确,不要处理整张图。
  • 减少不必要的绘制:img.draw_circle, img.draw_string这些函数在调试时很有用,但在最终稳定运行时可以注释掉,能节省一些时间。
  • 非阻塞式设计:主循环里,图像采集和处理是连续的,但AI决策和串口发送不必每帧都进行。可以设置一个标志位,只有当检测到棋盘状态发生变化(比如玩家落子)时,才触发AI决策流程。

5.2 提升视觉鲁棒性

  • 应对光照变化:除了动态阈值,可以考虑使用直方图均衡化(img.histeq())来增强图像对比度,或者尝试在红外光(如果OpenMV支持)下进行,以减少可见光环境的影响。
  • 多帧投票决策:对于棋子有无的判断,不要相信单帧的结果。可以连续检测3-5帧,只有当超过一半的帧数都认为某个格子有黑子(或白子)时,才更新board状态。这能有效过滤掉偶尔的识别抖动。
  • 棋盘丢失重校准:虽然我们用了“一次校准”,但如果棋盘被严重遮挡或摄像头被碰歪了怎么办?可以增加一个逻辑:定期(比如每100帧)用很低的计算量粗略检查一下之前存储的corners区域是否还是棋盘(例如检查区域平均颜色或边缘特征),如果丢失,则重新触发一次校准流程。

5.3 从三子棋到更复杂的博弈

这个项目的框架具有很强的扩展性。一旦你掌握了“视觉感知 -> 状态抽象 -> AI决策 -> 控制执行”这个闭环,就可以尝试更复杂的游戏,比如五子棋、国际象棋残局甚至简单的抓取积木并分类。

对于更复杂的游戏,AI决策算法需要升级。你可以研究Minimax算法及其优化版本Alpha-Beta剪枝,它们能在有限的搜索深度内找到最优解。虽然OpenMV的MicroPython环境计算能力有限,但对于五子棋的早期几步或简化棋盘的国际象棋,进行3-4层深度的搜索还是有可能的。这将会是对你算法设计和代码优化能力的极大挑战和锻炼。

最后,别忘了项目展示。用3D打印一个漂亮的棋盘底座,把OpenMV和机械臂整洁地固定好,再写一个简单的LCD显示屏界面来显示当前棋盘状态和胜负信息,一个充满极客魅力的智能对弈机器人就诞生了。这个过程里学到的,远不止是几行代码,而是解决一个完整软硬件结合问题的系统思维和工程能力。

5分钟带你重置Gitlab管理员账户密码 前言:  在使用gitlab的过程中,难免会出现忘记了管理员root账户密码的时候,这时候就需要进行管理员账户密码重置,下面就演示一下整个重置过程。 重置密码  官方文档说明:https://docs.gitlab.com/ee/security/reset_user_password.html  1.重置root密码之前,需先使用root用户登录到gitlab所在服务器。并且进入gitlab容器中,使用以下命令启动Ruby on Rails控制台。   gitlab-rails console -e pr 阅读详情

相关推荐

从视觉到决策:基于OpenMV的三子棋AI对弈系统全栈实现(含抗干扰与串口控制)

本文详细介绍了基于OpenMV的三子棋AI对弈系统的全栈实现方案。系统通过OpenMV摄像头完成棋盘定位与棋子识别,利用AI决策算法计算出最佳落子点,并通过串口通信控制机械臂执行动作。文章重点探讨了视觉抗干扰、棋盘状态管理及可靠的串口控制协议,为嵌入式机器视觉与AI集成项目提供了完整实践指南。

weixin_28273593的博客 509

Gitlab 忘记管理员密码

忘记 Gitlab 管理员密码,重置密码解决方案!

RAB 1857

从视觉到决策:基于OPENMV的三子棋AI系统全栈实现(含抗干扰、串口通信与简易博弈算法)

本文详细介绍了基于OPENMV的三子棋AI系统全栈实现,涵盖视觉识别、抗干扰处理、串口通信与轻量级博弈算法。通过动态阈值调整、ROI锁定策略和双阈值颜色识别等技术,有效解决了环境光变化和误识别问题。系统采用位运算优化胜负判断,并实现带优先级的AI决策逻辑,最终通过自定义串口协议与机械臂协同完成闭环控制。

weixin_42531163的博客 205

Gitlab私服管理员账户忘记密码

记得密码设置的是******,但是登录时一直出现错误,查看初始的密码也发现由于已经设置过了密码,初始密码文件也被删除了,只能重置了。如果密码忘记了登录不进入,可以先尝试点击登录框下方的忘记密码来通过邮箱的方式找回,但是要是就这么找回了也就不会有这篇博客了。虽然我的Gitlab是容器化部署的,但基本流程都是一样的,并不影响,查看当前容器。进入gitlab控制台,如果卡住可以多等一会。接下来就可以返回gitlab登录界面重新登录。重置密码并保存用户对象(设置自己的密码代替。切换到git用户目录下。

m0_62943934的博客 1800

OpenMV三子棋实战:从棋盘识别到AI下棋,一个完整嵌入式视觉项目的避坑指南

本文详细解析了使用OpenMV实现三子棋从棋盘识别到AI决策的全流程,涵盖硬件选型、动态校准、棋子检测、AI策略及机械臂协同控制等关键环节。通过混合策略优化识别效率,结合HSV色彩空间与形状检测提升稳定性,并设计三级缓冲机制解决通信延迟问题,为嵌入式视觉项目提供实用避坑指南。

weixin_30919429的博客 375

OpenMV三子棋机械臂实战:电赛E题核心代码解析与优化

本文详细解析了2024年电赛E题OpenMV三子棋机械臂的核心实现与优化方案。通过Minimax算法与α-β剪枝提升AI决策效率,结合视觉识别优化与舵机平滑控制算法,解决机械臂抖动、定位漂移和识别误差等关键问题,为电赛参赛者提供了一套稳定可靠的自动对弈系统实现方案。

w1x2y3的博客 272

GitLab重置root管理员密码

  不知道咋滴,用着Gitlab突然给我退出到了登录界面,可能是登录会话过时了吧,又或者是我更改了用户名吧,因为用户名和代码路径强相关,我为了让代码路径看着更顺眼,所以更改了用户名。但是退出到登录界面后我再也无法登录进入主页了,于是想着更改管理员账户密码,折腾了半天终于改好了~

黄勇的博客 7417

基于OpenMV与机械臂的AI视觉拼图系统:从手眼标定到自主抓放

计算机视觉与机器人运动控制是智能自动化领域的核心技术。其原理在于通过摄像头等传感器获取环境信息,经算法处理后,引导执行机构完成特定任务。这项技术的核心价值在于实现“感知-决策-执行”的闭环,将AI的认知能力与物理世界的操作能力相结合。在应用场景上,它广泛覆盖了工业分拣、自动化装配、教育机器人以及各类机器人竞赛项目。本文聚焦于一个结合了端侧AI与机械臂控制的具体实践案例:使用星瞳科技的OpenMV智能摄像头,通过AprilTag识别和手眼标定技术,驱动机械臂自主完成七巧板拼图任务。该项目完整展示了从视觉感知、

weixin_42570484的博客 358

从视觉到决策:基于OpenMV的三子棋AI视觉系统全链路实现(含抗干扰与通信)

本文详细介绍了基于OpenMV的三子棋AI视觉系统全链路实现方案。系统通过摄像头采集图像,采用抗干扰算法稳定识别棋盘与棋子状态,构建棋盘数字模型并集成AI决策算法,最终通过串口通信控制机械臂完成自动对弈。重点解决了环境光线变化等工程难题,提供了从视觉感知到决策执行的完整嵌入式AI实践指南。

3a9bq4r8t2y的博客 239

从棋盘识别到智能决策:OpenMV在电赛中的视觉与AI实战

本文详细介绍了OpenMV在电子设计竞赛中的视觉与AI实战应用,重点探讨了棋盘识别、角度计算和智能决策的实现方法。通过优化矩形检测、灰度转换和动态阈值等技术,提升了系统在复杂光照条件下的稳定性。文章还分享了井字棋决策算法的简化策略和实时性优化技巧,为电赛选手提供了宝贵的实战经验。

weixin_26834815的博客 246

基于OpenMV的AI机械臂视觉识别与自主拼图实战

机器视觉是赋予机器“眼睛”和“大脑”的关键技术,其核心原理是通过图像传感器采集信息,并利用算法进行处理与理解。这项技术的价值在于实现自动化、智能化的感知与控制,广泛应用于工业自动化、机器人导航、智能检测等领域。在嵌入式系统与机器人开发中,端侧AI和边缘计算正成为趋势,它们将AI推理部署在设备端,以实现低延迟、高集成的实时响应。本文聚焦于一个具体的工程实践:如何利用星瞳科技的OpenMV端侧AI智能摄像头,结合颜色识别、轮廓查找等机器视觉算法,解决机器人对七巧板拼图块的识别、定位与姿态估计问题,并完成与机械臂

weixin_42550597的博客 266

三子棋背后的算法博弈:Minimax决策树与机器视觉的融合艺术

本文深入探讨了三子棋机器人系统中Minimax决策树算法与机器视觉的融合应用。通过OpenMV平台实现图像采集与棋盘状态解析,结合舵机控制机械臂精准落子,详细解析了算法优化、视觉处理流程及嵌入式资源分配策略,为边缘AI应用开发提供实战参考。

gold8的专栏 204

2024电赛E题三子棋Python源码解析:从minimax到串口协议

在嵌入式竞赛与自动化装置开发中,上位机与下位机的协同设计是系统工程的核心挑战。博弈算法作为决策引擎,常与资源受限的MCU形成算力矛盾,因此需要采用α-β剪枝等优化策略。串口通信协议则是连接视觉模块与执行机构的桥梁,固定帧长与校验机制能有效保障数据可靠性。状态机编程为多模块联动提供了清晰的控制流,确保系统在异常场景下的鲁棒性。本文围绕2024电赛E题三子棋游戏,深入拆解其Python源代码,重点分析棋盘建模、minimax决策、串口帧格式、OpenMV视觉识别及主控状态机的工程实现,并总结赛场上容易导致失败的

weixin_42524703的博客 277

星瞳OpenMV官方机械臂教程|Robot Arm三子棋人机对战

欢迎来到OpenMV官方机械臂第三期教程——有趣的三子棋人机对战!快来跟着视频打造你的“下棋搭子”吧! 下期还将展示如何在此基础上完成24年电赛E题,敬请期待哦~

SingTown_OpenMV的博客 512

流媒体协议-RTMP简介

与rtsp 不同,RTSP(Real-Time Streaming Protocol)是一个控制协议,负责控制媒体流的传输,但不传输媒体数据本身。RTSP 可以通过 TCP 或 UDP 传输 RTP 包来传输音视频数据。 RTMP(Real-Time Messaging Protocol)是一个综合性的协议,不仅可以传输音视频数据,还可以传输信令控制指令。RTMP 使用 TCP 作为传输协议,可以直接在 TCP 连接上传输音视频数据,也可以传输控制指令,实现了音视频流的实时传输和控制

xiaoshuaijinniu的博客 4552

国密套件ECC-SM2-SM4-CBC-SM3和ECDHE-SM2-WITH-SM4-SM3

双方交换各自的公钥,最后A计算点(x1,y1) = d1Q2,B计算点(x2,y2) = d2Q1,由于椭圆曲线上是可以满足乘法交换和结合律,所以 d1Q2 = d1d2G = d2d1G = d2Q1 ,因此双方的 x 坐标是一样的,所以它是共享密钥,也就是会话密钥。4、客户端和服务端分别使用工作密钥,计算主密钥,客户端随机数,服务端随机数,字符串常量"key expansion",经PRF计算生成工作密钥。工作密钥包括加密密钥和校验密钥,具体密钥长度由选择的密码算法决定。客户端支持的压缩算法列表。

Java学习笔记 3784

从零开始搭建三子棋人机对战装置:基于Arduino的机械臂控制与棋盘识别教程

本文详细介绍了如何从零开始搭建基于Arduino的三子棋人机对战装置,涵盖机械臂控制、棋盘识别和AI决策系统的全流程实现。通过硬件选型、运动控制算法优化和视觉识别技术,打造具备自主决策能力的智能对战系统,为创客和机器人爱好者提供实用教程。

749

2026年7月19日 从可插拔到共封装:技术路线研究报告

AI 算力的爆发正在重写数据中心光互连的技术路线。本报告对当前并存的四代光互连架构——

weixin_51184047的博客 588

从像素到智能决策:OpenMV如何重塑嵌入式机器视觉的开发范式

本文探讨了OpenMV如何通过基于MicroPython的智能摄像头模块,降低嵌入式机器视觉的开发门槛。OpenMV将复杂算法封装为简单Python接口,支持颜色追踪、AprilTag定位和深度学习集成,重塑了开发范式,使开发者能专注于业务逻辑而非底层实现。

git9versioner的博客 659

ESD防护设计宝典(十一):CE(传导发射)超标问题排查与解决

(Conducted Emission, CE),亦称为传导骚扰,是电子电气设备或系统内部的电压、电流通过信号线、电源线或地线向外传输,对其他电子电气设备或系统造成电磁干扰的物理现象。其。

m0_56451176的博客 857

FOC 转子初始位置检测(图文详解)

什么是转子的初始位置? 其实转子的初始位置是不确定的,但是在电机启动的时候,我们需要得到电角度,这样才可以进行矢量控制;所以,这里将转子与A轴重合作为初始位置,此时电角度也恰好为零,具体如下图所示; ) 至于原理下面会详细分析,这样在转子到初始位置后,也可以得到准确的电角度,就可以实现磁场和转子的同步转动。 如何让转子运行到初始位置? 其实这是一个很简单的问题,在这里我将它放大了,简单地分析了一...

一名热爱技术的工程师的博客。分享技术干货,记录美好生活。永远相信美好的事情即将发生。 2万+

基于OpenClaw与OpenMV的边缘AI视觉监控系统:老人摔倒检测实战

边缘计算通过在数据源头就近处理信息,有效解决了云端AI方案在实时性、隐私和带宽成本上的痛点。其核心原理是将计算负载从中心服务器下放到网络边缘的设备,实现低延迟响应和数据本地化处理。这一技术价值在于为物联网和实时监控场景提供了可靠、高效的解决方案。在应用场景上,边缘AI特别适用于智能安防、工业检测、智慧养老等对实时性和隐私要求高的领域。本文以老人摔倒检测这一具体需求为切入点,详细阐述了如何利用OpenClaw智能体框架和OpenMV机器视觉模块,构建一个集感知、决策与执行于一体的分层系统架构。通过将轻量化姿态

weixin_32296621的博客 291

【ComfyUI】Animate 保留原视频背景角色替换视频生成

本文介绍了智能创作与视频生成的工作流设计,强调其作为围绕业务目标、数据流转和模型能力的有机整体。工作流由数据输入、模型处理、结果合成和输出展示构成,通过节点化连接实现高效复用与扩展。文章重点解析了核心模型(如CLIP Vision、WanVideo等)的功能和协作方式,以及各类节点(输入、处理、控制、输出)的作用。最后展示了工作流在视频角色替换、虚拟试衣等场景的应用价值,并提供了相关开发资源链接。该设计通过模块化实现了灵活适配不同业务需求的能力。

Mr数据杨 1867

电赛E题实战:基于STM32与OpenMV的运动目标视觉追踪系统全解析

视觉伺服系统是实现机器“眼睛”与“手脚”协同工作的核心技术,它通过摄像头感知环境,经控制器处理信息后驱动执行机构,构成一个实时闭环反馈。其核心原理在于将图像坐标通过数学模型(如小孔成像模型或比例系数法)转换为物理世界的角度或位置偏差,再运用PID等控制算法进行动态调节。这项技术的价值在于实现了高精度、自动化的实时响应,广泛应用于工业自动化、机器人导航、智能监控等领域。本文以全国大学生电子设计竞赛(电赛)经典赛题为背景,深入剖析了如何利用STM32微控制器与OpenMV视觉模块,构建一个完整的运动目标自动追踪

weixin_30902251的博客 482

从被秒封到稳过Cloudflare!Canvas/WebGL/WebRTC多维度浏览器指纹隐身全实战

反爬和反反爬,本质上是一场持续的博弈,没有100%的隐身,只有不断升级的伪装。网上很多教程只给了个基础的噪声代码,却没讲透反爬的检测逻辑,导致你用了还是被封。这套方案的核心,不是简单的API重写,而是站在反爬的角度,模拟真实用户的所有特征,保证所有指纹的一致性、合理性、完整性。目前这套方案我用了半年,跑了上千万次请求,稳过国内国外99%的主流反爬平台,没有出现过一次因为指纹关联导致的批量封禁。大家有什么更狠的反爬场景,或者更好的伪装技巧,欢迎评论区一起交流。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1194

机器人轨迹规划——梯形速度轨迹(超详细)

机器人轨迹 这一系列轨迹教程将主要包括以下内容: 点到点轨迹(P2P) 五次多项式插值轨迹 三次多项式插值轨迹 梯形速度曲线轨迹 双S形速度曲线轨迹 多个自由度轨迹的时间同步 在线轨迹规划 多项式在线轨迹规划 梯形在线轨迹规划 双S形在线轨迹规划 非线性实时轨迹滤波 多点轨迹(Multi-point) 三次样条曲线(cubic spline) 贝赛尔曲线(Bezier Curve) B样条曲线(BSpline) 时间最优轨迹 三次样条时间最优轨迹 任意路径下的时间最优轨迹 时间

出门搔白首,若负平生志 1万+
上一篇: 优化DMA串口通信:避免数据覆盖的实战策略
下一篇: EMC与ESD防护实战:磁珠与磁环的选型技巧及高频电路设计优化
Light
博客等级 码龄27年 39粉丝 1340原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值