首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从棋盘游戏中提取棋子和位置

从棋盘游戏中提取棋子和位置
EN

Stack Overflow用户
提问于 2022-09-19 12:38:24
回答 1查看 45关注 0票数 0

因此,我使用OpenCV (在Go with OpenCV中)尝试从一个木板游戏中提取碎片。最初,我在处理这个问题时取得了一定的成功,手动找到了每个球员的HSV值、颜色和棋盘位置。我成功地做到了这一点,并对每一件作品及其在董事会中的位置进行了规划。缺点是,如果使用不同的板--“查找”所有正确的HSV值,则需要相当严重的人与人之间的交互。I asked here建议从忽略颜色开始,找出所有的片段,然后使用颜色聚类算法来确定它是哪一个播放器。我可能也得为这些职位做点什么,但那是第二阶段。

所以现在我试着把所有的片段都提取出来,不管颜色。

我一开始试着使用NewSimpleBlobDetectorWithParams --尽管没有取得什么进展,但它似乎在错误的否定/阳性方面挣扎了很多。

我尝试了HoughCirclesWithParams,但这似乎非常依赖于参数,而且在实际检测到的部分中,我没有取得多大进展。目前我正在使用FindContours,这似乎给了我一些合理的准确性。让我们看看这些照片。

原始图像如下:

我已经建立了一个控制的“仪表板”,似乎最“有用”的东西是侵蚀、膨胀和门槛。

我当前的设置是一个负载的trackerbars/滑块来调整值,然后

代码语言:javascript
复制
            gocv.CvtColor(clone, &clone, gocv.ColorRGBToGray)
            erodeKernel := gocv.GetStructuringElement(gocv.MorphRect, image.Pt(trackers.erosionValue, trackers.erosionValue))
            gocv.Erode(clone, &clone, erodeKernel)
            dilateKernel := gocv.GetStructuringElement(gocv.MorphRect, image.Pt(trackers.dilateValue, trackers.dilateValue))
            gocv.Dilate(clone, &clone, dilateKernel)
            gocv.Threshold(clone, &clone, float32(trackers.thresTruncValue), 255, gocv.ThresholdTrunc)
            gocv.Threshold(clone, &clone, float32(trackers.threshBinaryValue), 255, gocv.ThresholdBinary)
            cannies := gocv.NewMat()
            gocv.Canny(clone, &cannies, float32(trackers.cannyMin), float32(trackers.cannyMax))
            cnts := gocv.FindContours(cannies, gocv.RetrievalTree, gocv.ChainApproxSimple)

紧接着是

代码语言:javascript
复制
            for i := 0; i < cnts.Size(); i++ {
                cnt := cnts.At(i)
                if len(cnt.ToPoints()) < 5 {
                    continue
                }
                rect := gocv.FitEllipse(cnt)
                gocv.Circle(&colorImage, image.Pt(rect.Center.X, rect.Center.Y), (rect.Height + rect.Width)/4, cntColor, 3)

                if gocv.ContourArea(cnt) < gocv.ArcLength(cnt, false) {
                    continue
                }
                gocv.Rectangle(&colorImage, rect.BoundingRect, rectColor, 2)
                psVector := gocv.NewPointsVector()
                psVector.Append(cnt)
                gocv.DrawContours(&clone, psVector, 0, rectColor, 3)
                if rect.Center.X == (rect.BoundingRect.Max.X + rect.BoundingRect.Min.X) / 2 && rect.Center.Y == (rect.BoundingRect.Min.Y + rect.BoundingRect.Max.Y) / 2 {
                    //Does the circle fit inside the square?
                    if float64(rect.Width * rect.Height) > math.Pi * math.Pow(float64((rect.Height+rect.Width)/4), 2) {
                        gocv.Circle(&colorImage, image.Pt(rect.Center.X, rect.Center.Y), 2, matchColor, 3)
                        pieces = append(pieces, image.Pt(rect.Center.X, rect.Center.Y))
                    }
                }
            }

这个想法是,如果轮廓有5个点,你就可以找到包围矩形,如果轮廓是封闭的,在轮廓中心画一个圆圈,如果它适合于边界矩形,它们共享相同的中心,可能是一个弹奏片。注意--我想出了这个原则,它是基于观察圆圈和包围矩形的位置,当它们匹配起来的时候,它看起来更像是一个弹奏曲。

所以我正在取得一些很好的进展。然而,我的问题是帮助挖掘出其他颜色的片段,也许更“有力”地挖出白色的部分。我觉得我没有足够的工具可供我支配,好像我增加了一件事,我不得不减少另一件事,而且由于某种原因,我觉得在一块板上找到30轮chequers应该是相当健壮的。当我调整值寻找栗色碎片时,我可以得到其中的一些。

但是,正如你所看到的,当你玩门槛/侵蚀/膨胀时,这种差异并不能很好地找到它们。

编辑:

我加入了hough循环算法,以显示它经常会碰到假负片--在这种情况下,它得到了1。

代码语言:javascript
复制
            gocv.HoughCirclesWithParams(
                clone,
                &circles,
                gocv.HoughGradient,
                1,                     // dp
                15, // minDist
                75,                    // param1
                20,                    // param2
                20,                    // minRadius
                45,                     // maxRadius
            )
            blue := color.RGBA{0, 0, 255, 0}
            for i := 0; i < circles.Cols(); i++ {
                v := circles.GetVecfAt(0, i)
                // if circles are found
                if len(v) > 2 {
                    x := int(v[0])
                    y := int(v[1])
                    r := int(v[2])
                    gocv.Circle(&colorImage, image.Pt(x, y), r, blue, 2)
                }
            }

这是我用的门槛。

所以我意识到我在这里说了很多。我正在寻找一些帮助,以发现在董事会上的所有播放部分。我是在gocv中这样做的,但是如果有人有一个很好的引用或其他东西,我可以使用python /转换python代码。

没有任何修正的原始图像就在这里。正如我所说的,我的目标是自动检测板上的30块,然后我可以使用聚类算法来确定它们属于哪一组(我认为.)我想用最少的人的交互,拖动滑块,因为这不是一个有趣的/良好的用户体验.

我的想法

  • 用户可以在组中拖动包围框,这样计算机就可以更容易地知道必须在其中查找部件。用户可以选择页面的颜色,这将告诉计算机它在
  • 中应该查看的HSV值大致是多少,用户可以根据已知的开始位置进行校准,以便计算机知道应该在哪里查找。

EN

回答 1

Stack Overflow用户

发布于 2022-09-20 09:22:15

这并不完全是你的问题的答案,但如果你用目标检测来代替,这就容易多了。在我的教程中,我也找到了不同的对象。在这种情况下,我将有2个或3个类别:光片,暗片,可能还有另一个空空间类。

我通常使用OpenCV和Darknet/YOLO来解决这些问题。我的youtube频道上有很多教程。这里有一个简单的方法来检测一些形状:https://www.youtube.com/watch?v=yOJIRArZeig,这里是另一个显示用于解决Sudoku:https://www.youtube.com/watch?v=BUG7HlhuArw的OpenCV和Darknet/YOLO的

你的案子会和上一个类似。您将得到检测到的对象向量,其中包含图像或视频帧中每个对象的边界框坐标。如果有兴趣,这是我推荐开始的教程视频:https://www.youtube.com/watch?v=pJ2iyf_E9PM

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73773468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档