def __init__(self, offset, size ): ''' constructor @param offset: The top-left corner of the pocket reltavie to 0,0 in the main image @param emptyImage: The image to be used to check if the pocket is empty ''' self._PointTL = offset self._PointBR = offset+size - point(1,1)
def initPockets(self, emptyImageList ): ''' generates the pocket objects with default data ''' self.pockets = {} for col in range(0, self.gridsize.x): for row in range(0, self.gridsize.y): pointTL = self._PointTL + point( col*self.pocketsize, row*self.pocketsize) self.pockets[(col, row)] = pocket( pointTL, emptyImageList[(col, row)] )
def ReadScore(self, image ): digits = [] widthadj = 0 for i in range( 0, len( self._digit_rel_loc ) ): imToFind = self._digitelements[i].getImage( image ) item = self._digitlist.findItem( imToFind ) if item == None: # TODO: better handling of blanks. # filename = 'digit_loc_%02d.png'%i # cv2.imwrite( filename, imToFind ) # print >> sys.stderr, "digit not recognized: %s"%filename pass else: digits.append( item ) res = self._digitlist.getLastResult()[item] size = point( *self._digitlist.getSize( item ) ) widthadj = widthadj + res[3][0] self._digitelements[i] = Digit(self._digitelements[i].pointTopLeft+point(res[3][0], res[3][1]), size ) if i+1 < len( self._digit_rel_loc ): defaultDistance = 3 # dist between digits if (i+1) % 3 == 0: ExtraOffset = point( 12+defaultDistance, 0 ) else: ExtraOffset = point( 0+defaultDistance, 0 ) # recreate digit with better start point self._digitelements[i+1] = Digit(self._digitelements[i].pointTopLeft \ - point( self._defaultDigitSize.x, 0) - ExtraOffset, self._defaultDigitSize ) # calculate the integer value digitssum = 0 for i in range( 0, len(digits) ): digitssum = digitssum + digits[i]*10**i return digitssum
def FindCorner( image, screwtemplate, ShowTracking = False ): ''' using the template, the corner screw is found @return: the position of the corner screw ''' result = cv2.matchTemplate(screwtemplate,image,cv2.TM_CCORR_NORMED) minval, maxval, minloc, maxloc = cv2.minMaxLoc(result) # @UnusedVariable if maxval < 1.0: print >> sys.stderr, "Note: match should be 100%%, was %f"%(maxval*100,) if ShowTracking: w,h = screwtemplate.shape[:2] cv2.rectangle(image, maxloc, (maxloc[0]+w, maxloc[1]+h), color_red ) return point(maxloc[0], maxloc[1])
class pockets(BoardElement): pocketsize = 40 # measured and will never change :-) gridsize = point( 7 ,7 ) _currentImage = None def __init__(self, offset, emptyImageList ): ''' constructor @param offset: The top-left corner of the pocket reltavie to 0,0 in the main image @param emptyImage: The image to be used to check if the pocket is empty ''' super(pockets, self).__init__( offset, self.pocketsize*self.gridsize) # self._PointTL = offset # self._PointBR = offset+7*point(self.pocketsize, self.pocketsize ) - point(1,1) self.initPockets( emptyImageList ) def initPockets(self, emptyImageList ): ''' generates the pocket objects with default data ''' self.pockets = {} for col in range(0, self.gridsize.x): for row in range(0, self.gridsize.y): pointTL = self._PointTL + point( col*self.pocketsize, row*self.pocketsize) self.pockets[(col, row)] = pocket( pointTL, emptyImageList[(col, row)] ) # @property # def pointTopLeft(self): # return self._PointTL # # @property # def pointBottomRight(self): # return self._PointBR def processImage(self, image): for col in range( 0, self.gridsize.x): for row in range( 0, self.gridsize.y): if self.pockets[(col, row)].isEmpty( image ): #print >> sys.stderr, "[%d, %d] empty"%(col, row) continue # TODO: do we have an issue with shallow vs. deep copy here? self._currentImage = image # True means success return True def isEmpty(self, col, row): return self.pockets[(col, row)].isEmpty( self._currentImage) def ShowPocketBoundaries(self, color, bigImage): for col in range( 0, self.gridsize.x): for row in range( 0, self.gridsize.y): self.pockets[(col, row)].ShowBoundary( color, bigImage ) def getImage(self, col, row ): return self.pockets[(col, row)].getImage( self._currentImage) pass def ShowPocketValues(self, color, bigImage): for col in range( 0, self.gridsize.x): for row in range( 0, self.gridsize.y): self.pockets[(col, row)].ShowValue( color, bigImage ) def setValue(self, col, row, value ): self.pockets[(col, row)].setValue( value ) def getValue(self, col, row ): return self.pockets[(col, row)].value
def testPoint(self): p = point( 1,2 ) self.assertEqual( p.x, 1) self.assertEqual( p.y, 2) pass
''' Created on May 2, 2013 @author: moz ''' import unittest from data.pockets import pockets from data.point import point import numpy offsetPoint = point( 10, 20 ) gridsize = point(7 ,7) pocketSize = 40 smallBlackImage = numpy.zeros((pocketSize, pocketSize, 3), numpy.float32) bigWhiteImage = numpy.zeros((pocketSize*10, pocketSize*10, 3), numpy.float32) bigWhiteImage[:,:] = (255,255,255) # (B, G, R) bigBlackImage = numpy.zeros((pocketSize*10, pocketSize*10, 3), numpy.float32) emptyImageList = {} for col in range( 0, gridsize.x): for row in range( 0, gridsize.y): emptyImageList[(col, row)] = smallBlackImage class Test(unittest.TestCase): def testPockets(self): p = pockets( offsetPoint, emptyImageList ) self.assertEqual( p.pointTopLeft, offsetPoint ) self.assertEqual( p.pointBottomRight, offsetPoint+7*point(pocketSize, pocketSize) - point( 1, 1 ) ) pass
def testPocket(self): p = pocket(offsetPoint, smallBlackImage) self.assertEqual(p.pointTopLeft, offsetPoint) self.assertEqual(p.pointBottomRight, offsetPoint + point(pocketSize - 1, pocketSize - 1)) pass
def testBoardElement(self): be = BoardElement( offsetPoint, size ) self.assertEqual( be.pointTopLeft, offsetPoint ) self.assertEqual( be.pointBottomRight, offsetPoint+size+point(-1, -1) )
def ShowValue(self, color, overlayImage): org = (self._PointTL + point( 3, 13)).tupple cv2.putText(overlayImage, self.value, org, cv2.FONT_HERSHEY_PLAIN, 1.0, color, thickness=2 )
def testStr(self): p = point( 3, 4 ) self.assertEqual(str(p), "point: (3, 4)" )
def testMul(self): a,b = 6,7 m = 8 self.assertEqual( m*point( a, b ), point(m*a, m*b)) self.assertEqual( point( a, b )*m, point(m*a, m*b))
def testPointAdd(self): a,b,c,d = 1,2,3,4 p1 = point( a,b) p2 = point( c,d) self.assertEqual(p1+p2, point(a+c, b+d ) )
def testPointEqual(self): p1 = point( 3,4 ) p2 = point( 3,4 ) self.assertTrue(p1==p2)
def testPointTupple(self): p = point( 3, 4 ) self.assertEqual(p.tupple, (3,4) )
''' Created on May 4, 2013 @author: moz ''' import unittest from data.point import point from data.Digit import Digit offset = point( 3, 7) size = point( 15, 30 ) class Test(unittest.TestCase): def testDigit(self): d = Digit( offset, size ) self.assertNotEqual(d, None) if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testDigit'] unittest.main()
''' Created on May 4, 2013 @author: moz ''' import unittest from data.point import point from data.BoardElement import BoardElement import numpy offsetPoint = point( 10, 20 ) size = point( 35, 45 ) bigBlackImage = numpy.zeros((size.x*10, size.y*10, 3), numpy.float32) class Test(unittest.TestCase): def testBoardElement(self): be = BoardElement( offsetPoint, size ) self.assertEqual( be.pointTopLeft, offsetPoint ) self.assertEqual( be.pointBottomRight, offsetPoint+size+point(-1, -1) ) def testDrawBoundary(self): color = (0, 0, 255) p = BoardElement( offsetPoint, size ) bigImage = numpy.zeros((size.x*10, size.y*10, 3), numpy.float32) p.ShowBoundary( color, bigImage ) # yes, x and y are inverted... self.assertEqual( bigImage[ offsetPoint.y, offsetPoint.x ][0], color[0] )
''' Created on May 4, 2013 @author: moz ''' import unittest from data.point import point from data.BoardElement import BoardElement import numpy offsetPoint = point(10, 20) size = point(35, 45) bigBlackImage = numpy.zeros((size.x * 10, size.y * 10, 3), numpy.float32) class Test(unittest.TestCase): def testBoardElement(self): be = BoardElement(offsetPoint, size) self.assertEqual(be.pointTopLeft, offsetPoint) self.assertEqual(be.pointBottomRight, offsetPoint + size + point(-1, -1)) def testDrawBoundary(self): color = (0, 0, 255) p = BoardElement(offsetPoint, size) bigImage = numpy.zeros((size.x * 10, size.y * 10, 3), numpy.float32) p.ShowBoundary(color, bigImage) # yes, x and y are inverted... self.assertEqual(bigImage[offsetPoint.y, offsetPoint.x][0], color[0])
''' Created on May 2, 2013 @author: moz ''' import unittest from data.point import point from data.pocket import pocket import numpy # test data offsetPoint = point(10, 20) pocketSize = 40 smallBlackImage = numpy.zeros((pocketSize, pocketSize, 3), numpy.float32) bigWhiteImage = numpy.zeros((pocketSize * 10, pocketSize * 10, 3), numpy.float32) bigWhiteImage[:, :] = (255, 255, 255) # (B, G, R) bigBlackImage = numpy.zeros((pocketSize * 10, pocketSize * 10, 3), numpy.float32) #bigBlackImage[:,:] = (0,0,0) # (B, G, R) # # debug stuff # cv2.imshow( "bigWhiteImage", bigWhiteImage ) # cv2.imshow( "bigBlackImage", bigBlackImage ) # cv2.imshow( "emptyImage", emptyImage) # cv2.waitKey() class Test(unittest.TestCase): def testPocket(self): p = pocket(offsetPoint, smallBlackImage) self.assertEqual(p.pointTopLeft, offsetPoint)
def testBoardElement(self): be = BoardElement(offsetPoint, size) self.assertEqual(be.pointTopLeft, offsetPoint) self.assertEqual(be.pointBottomRight, offsetPoint + size + point(-1, -1))
''' Created on May 4, 2013 @author: moz ''' import unittest from data.point import point from data.Digit import Digit offset = point(3, 7) size = point(15, 30) class Test(unittest.TestCase): def testDigit(self): d = Digit(offset, size) self.assertNotEqual(d, None) if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testDigit'] unittest.main()
def testReadScoreC(self): sb = ScoreBoard(point(0, 0), il) scoreread = sb.ReadScore(scoreboard_C) self.assertEqual(scoreboard_C_score, scoreread)
def testPockets(self): p = pockets( offsetPoint, emptyImageList ) self.assertEqual( p.pointTopLeft, offsetPoint ) self.assertEqual( p.pointBottomRight, offsetPoint+7*point(pocketSize, pocketSize) - point( 1, 1 ) ) pass
screwtemplateTL = cv2.imread(ScrewFilenameTopLeft) screwtemplateBR = cv2.imread(ScrewFilenameBotomRight) fileno = 0 for screenshotfilename in glob.glob("Screenshots/*.png"): #for screenshotfilename in glob.glob("Screenshots/Screenshot - 2013-05-01 - 21:35:24.png"): image = cv2.imread( screenshotfilename ) # locate screw to fix image CornerTL = FindCorner( image, screwtemplateTL ) CornerBR = FindCorner( image, screwtemplateBR ) size = CornerBR -CornerTL # TODO: magic values! DropItemsAreaTL = CornerTL + point(15,95) DropItemsAreaBR = DropItemsAreaTL + point( 281, 80 ) ScoreBoardOffset = point( 71, 34 ) # scoreboard relative to screw curScoreBoard = ScoreBoard( CornerTL + ScoreBoardOffset, digits) CurScore = curScoreBoard.ReadScore(image) # red squares in matrix offset = point( DropItemsAreaTL.x, DropItemsAreaBR.y ) curPockets = pockets( offset, emptyImageList ) curPockets.processImage(image) fileno = fileno + 1 emptycount = 0 unknownCount = 0
class ScoreBoard(BoardElement): _size = point(184, 39) _digit_rel_loc = [ point( 160, 5 ), point( 143, 5 ), point( 126, 5 ), point( 95, 5 ), point( 78, 5), point( 61, 5 ), point( 30, 5 ) ] _defaultDigitSize = point(20, 29 ) def __init__(self, offset, digitlist ): ''' constructor ''' super(ScoreBoard, self).__init__( offset, self._size) self._digitlist = digitlist # bogus boardelements - specific location is fixed later. self._digitelements = [] for digit_loc in self._digit_rel_loc: self._digitelements.append( Digit(self.pointTopLeft+digit_loc, self._defaultDigitSize )) def ShowBoundary(self, color, overlayImage): super(ScoreBoard, self).ShowBoundary(color, overlayImage) for digit in self._digitelements: digit.ShowBoundary( color, overlayImage) def ReadScore(self, image ): digits = [] widthadj = 0 for i in range( 0, len( self._digit_rel_loc ) ): imToFind = self._digitelements[i].getImage( image ) item = self._digitlist.findItem( imToFind ) if item == None: # TODO: better handling of blanks. # filename = 'digit_loc_%02d.png'%i # cv2.imwrite( filename, imToFind ) # print >> sys.stderr, "digit not recognized: %s"%filename pass else: digits.append( item ) res = self._digitlist.getLastResult()[item] size = point( *self._digitlist.getSize( item ) ) widthadj = widthadj + res[3][0] self._digitelements[i] = Digit(self._digitelements[i].pointTopLeft+point(res[3][0], res[3][1]), size ) if i+1 < len( self._digit_rel_loc ): defaultDistance = 3 # dist between digits if (i+1) % 3 == 0: ExtraOffset = point( 12+defaultDistance, 0 ) else: ExtraOffset = point( 0+defaultDistance, 0 ) # recreate digit with better start point self._digitelements[i+1] = Digit(self._digitelements[i].pointTopLeft \ - point( self._defaultDigitSize.x, 0) - ExtraOffset, self._defaultDigitSize ) # calculate the integer value digitssum = 0 for i in range( 0, len(digits) ): digitssum = digitssum + digits[i]*10**i return digitssum
''' Created on May 2, 2013 @author: moz ''' import unittest from data.pockets import pockets from data.point import point import numpy offsetPoint = point(10, 20) gridsize = point(7, 7) pocketSize = 40 smallBlackImage = numpy.zeros((pocketSize, pocketSize, 3), numpy.float32) bigWhiteImage = numpy.zeros((pocketSize * 10, pocketSize * 10, 3), numpy.float32) bigWhiteImage[:, :] = (255, 255, 255) # (B, G, R) bigBlackImage = numpy.zeros((pocketSize * 10, pocketSize * 10, 3), numpy.float32) emptyImageList = {} for col in range(0, gridsize.x): for row in range(0, gridsize.y): emptyImageList[(col, row)] = smallBlackImage class Test(unittest.TestCase): def testPockets(self): p = pockets(offsetPoint, emptyImageList) self.assertEqual(p.pointTopLeft, offsetPoint) self.assertEqual(