我一直致力于课堂作业,骰子识别和点数计数,给出了OpenCV的骰子图像。我的实现大部分都是正确的,我的程序能够在大多数情况下计算骰子。但是,我用来定义骰子区域的方框并不总是正确绘制。
所以这是我开始的图像: https://i.imgur.com/tv0arJu.jpg
运行程序后,我得到了这个输出: https://i.imgur.com/nvmyCgy.png
大多数情况下,我会得到倾斜45度的装订盒。此外,右下方的骰子被识别为3但是我执行的某些阈值处理的问题较小,所以这里不是问题。
所以我的程序的一般流程如下: 将图片的黑白版本发送到cv2.findContours。它返回的第二个值是段/轮廓列表:
_, segmented, hierarchy = cv2.findContours(bwImg.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
从那里我尝试使用这种方法在骰子周围放置一个矩形:
def fitRectangle(pyramid, bwImg, diceSize):
#Fit and resize rectangle to predefined dice size
rect = cv2.minAreaRect(pyramid)
rect = (rect[0], (rect[1][0] + diceSize, rect[1][1] + diceSize), rect[2])
floatRect = cv2.boxPoints(rect)
intRect = np.int0(floatRect)
bwImg = cv2.drawContours(bwImg, [intRect], 0, (255, 255, 255), -10)
a, b, c, d = cv2.boundingRect(intRect)
p1 = floatRect
p2 = np.float32([[a,b], [a+c, b], [a, b+d], [a+c, b+d]])
cv2.warpPerspective(bwImg, cv2.getPerspectiveTransform(p1, p2), p2.shape)
请注意,由于盒子大小是骰子大小的3倍,因为骰子在我们正在测试的所有图片中大致是静态大小。由于我的实施目前正在将盒子旋转45度,因此我增加了盒子的大小以适应整个骰子。如果我不这样做,我会得到这样的结果: https://i.imgur.com/Au0DxSl.png
此时,我已经陷入了困境。我不确定是什么导致我在矩形中进行这种旋转我会在我的其他一些测试中导致一些非常糟糕的结果,其中触摸的盒子合并到一个区域: https://i.imgur.com/b3EKTln.png
如果您有任何想法可能是罪魁祸首,我们将非常感谢任何帮助
编辑: 我意识到包含我的所有轮廓代码可能很重要:
def getContours(segmented, original, bwImg, diceSize, bwThreshold):
#Capture small contours
_, segmented, hierarchy = cv2.findContours(bwImg.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#Fit rectangle onto pyramid
for pyramid in segmented:
fitRectangle(pyramid, bwImg, diceSize * 3)
#Capture large contours
_, contours, hierarchy = cv2.findContours(bwImg.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#contours = segmented
#Get pips based on beThreshold
pips = 255 - cv2.threshold(original, bwThreshold, 255, 1)[1]
#Get only pips without dice
onlypips = cv2.bitwise_and(bwImg, pips)
dice = cv2.cvtColor(onlypips, cv2.COLOR_GRAY2RGB)
errorDice = 0
results = [0,0,0,0,0,0]
#Count pips in each die
for contour in contours:
pips, a, b = getNumPips(contour, onlypips)
#print (pips)
#If a die has more than 6 or less than 0 pips it is not a valid die
if pips > 6 or pips == 0:
errorDice += 1
else:
results[pips - 1] = results[pips - 1] + 1
cv2.putText(dice,str(pips),(a,b-5),0,10,(255,255,255), 25)
return contours, dice, errorDice, results