def extractCards(fileName=None): """ Given an image, this will extract the cards from it. This takes a filename as an optional argument This filename should be the name of an image file. This returns a dictionary of the form: (x, y) : Card image It is likely that the output from this will go to the getMeaningFromCards() function. """ if fileName == None: mat = takeScreenCapture() else: mat = cv.LoadImage(fileName) # First crop the image: but only crop out the bottom. # It is useful to have all dimensions accurate to the screen # because otherwise they will throw off the mouse moving and clicking. # Cropping out the bottom does not change anything in terms of the mouse. unnec_top_distance = 130 unnec_bottom_distance = 40 margin = 50 submat = cv.GetSubRect( mat, (0, 0, mat.width, mat.height - unnec_bottom_distance)) subImg = cv.CreateImageHeader((submat.width, submat.height), 8, 3) cv.SetData(subImg, submat.tostring()) gray = cv.CreateImage((submat.width, submat.height), 8, 1) cv.CvtColor(submat, gray, cv.CV_RGB2GRAY) thresh = 250 max_value = 255 cv.Threshold(gray, gray, thresh, max_value, cv.CV_THRESH_BINARY) cv.Not(gray, gray) #cv.ShowImage("sub", submat) #cv.WaitKey(0) storage = cv.CreateMemStorage(0) cpy = cv.CloneImage(gray) contours = cv.FindContours(cpy, storage, cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_SIMPLE, (0, 0)) #contours = cv.ApproxPoly(contours, cv.CreateMemStorage(), cv.CV_POLY_APPROX_DP, 3, 1) bboxes = [] if contours: while (contours): area = cv.ContourArea(contours) # It turns out that all the cards are about 44000 in area... # It would definitely be nice to have a better way to do this: # ie, find the size of the card programmatically and use it then if (area > 44000 and area < submat.width * submat.height * 2 / 3): bb = cv.BoundingRect(contours) bboxes.append(bb) contours = contours.h_next() #drawBoundingBoxes(bboxes, submat) # cards is a dictionary of the form: # (x, y) : card cards = {} for box in bboxes: card = cv.GetSubRect(subImg, box) #cv.ShowImage("card", card) #cv.WaitKey(0) cards[(box[0], box[1])] = card return cards
p_diffThreshold = 40 cv.AbsDiff(bggray, gray, frameDiff) frameDiffFundoSaida = cv.CloneImage(frameDiff) cv.Threshold(frameDiff, frameDiff, p_diffThreshold, 255, cv.CV_THRESH_BINARY) #for i in range(2): cv.Erode(frameDiff,frameDiff) #zera diferenca onde ha sombra frameSemSombra = cv.CloneImage(imgSombra) # dilata sombra para pegar qualquer borada de sombra #for i in range(2): cv.Erode(frameSemSombra,frameSemSombra) for i in range(2): cv.Dilate(frameSemSombra, frameSemSombra) # inverte e faz um AND cv.Not(frameSemSombra, frameSemSombra) cv.And(frameSemSombra, frameDiff, frameSemSombra) frameDiff = cv.CloneImage(frameSemSombra) frameDiffSemSombra = cv.CloneImage(frameDiff) ''' Faça uma cópia da imagem. Dê um cvSmooth com método CV_MEDIAN para tirar ruídos da cópia. Dê open (erode + dilate) na cópia. O Erode deve eliminar os ruídos restantes. Você pode usar um kernel horizontal e depois um vertical. Faça os dilates terem 1 grau a mais que o erode (na imagem final o branco que restará é maior que na original)
gray = cv.CreateImage((img.width, img.height), cv.IPL_DEPTH_8U, 1) binary = cv.CreateImage(cv.GetSize(img), cv.IPL_DEPTH_8U, 1) msk = cv.CreateImage((img.width + 2, img.height + 2), cv.IPL_DEPTH_8U, 1) dst = cv.CreateImage((img.width, img.height), cv.IPL_DEPTH_8U, 1) #cv.NamedWindow("gray", cv.CV_WINDOW_AUTOSIZE) #cv.NamedWindow("bin", cv.CV_WINDOW_AUTOSIZE) cv.NamedWindow("test1", cv.CV_WINDOW_AUTOSIZE) cv.NamedWindow("test2", cv.CV_WINDOW_AUTOSIZE) #cv.NamedWindow("test3", cv.CV_WINDOW_AUTOSIZE) #cv.NamedWindow("test4", cv.CV_WINDOW_AUTOSIZE) #cv.NamedWindow("test5", cv.CV_WINDOW_AUTOSIZE) cv.CvtColor(img, gray, cv.CV_RGB2GRAY) cv.Not(gray, gray) cv.Threshold(gray, binary, 20, 255, cv.CV_THRESH_BINARY) color = 100 color_list = [] for x in range(binary.width): for y in range(binary.height): if (binary[y, x] > color): cv.FloodFill(binary, (x, y), color, cv.ScalarAll(10), cv.ScalarAll(10), 0, msk) color_list.append(color) color = color + 1 obj = [] l_x = 0 r_x = 0
def process_image(image_color, name='unnamed.jpg'): #image_color = cv2.resize(image_color, (1280, 848)) image_color = cv2.blur(image_color, (3, 3)) image_hsv = array2cv(cv2.cvtColor(image_color, cv.CV_BGR2HSV)) mask1 = cv.CreateImage(cv.GetSize(image_hsv), 8, 1) mask2 = cv.CreateImage(cv.GetSize(image_hsv), 8, 1) mask_both = cv.CreateImage(cv.GetSize(image_hsv), 8, 1) demasked = cv.CreateImage(cv.GetSize(image_hsv), 8, 3) cv.Rectangle(demasked, (0, 0), cv.GetSize(image_hsv), cv.CV_RGB(255, 255, 255), cv.CV_FILLED) cv.InRangeS(image_hsv, cv.Scalar(0, 64, 100), cv.Scalar(150, 255, 255), mask1) cv.InRangeS(image_hsv, cv.Scalar(150, 64, 100), cv.Scalar(180, 255, 255), mask2) cv.Or(mask1, mask2, mask_both) cv.Not(mask_both, mask_both) cv.Copy(array2cv(image_color), demasked, mask_both) _, tmp = tempfile.mkstemp('.png') cv.SaveImage(tmp, demasked) demasked = cv2.imread(tmp) os.unlink(tmp) image = cv2.cvtColor(demasked, cv.CV_RGB2GRAY) image = cv2.equalizeHist(image) #image = cv2.blur(image, (3, 3)) image = cv2.dilate(image, None, iterations=2) _, image = cv2.threshold(image, 80, 255, cv.CV_THRESH_BINARY + cv.CV_THRESH_OTSU) h, w = image.shape MIN_AREA = 100 MIN_WIDTH = w * 0.1 MAX_WIDTH = w * 0.5 EPSILON = 0.1 TEMPLATE = cv.LoadImage('template.jpg', 0) storage = cv.CreateMemStorage() TEMPLATE_CONTOURS = cv.FindContours(TEMPLATE, storage, mode=cv.CV_RETR_EXTERNAL, method=cv.CV_CHAIN_APPROX_NONE, offset=(0, 0)) storage = cv.CreateMemStorage() im_cv = array2cv(image) im_cv_c = array2cv(cv2.cvtColor(image, cv.CV_GRAY2RGB)) cv.XorS(im_cv, cv.Scalar(255, 0, 0, 0), im_cv, None) contours = cv.FindContours(im_cv, storage, mode=cv.CV_RETR_EXTERNAL, method=cv.CV_CHAIN_APPROX_NONE, offset=(0, 0)) if contours: cv.DrawContours(im_cv, contours, (0, 0, 0), (0, 0, 0), 7, -1) biggestCircle = None BC_cnt = None while contours: area = cv.ContourArea(contours) if area < MIN_AREA: contours = contours.h_next() continue storage2 = cv.CreateMemStorage(0) hull = cv.ConvexHull2(contours, storage2, cv.CV_CLOCKWISE, 1) if hull: cv.PolyLine(im_cv_c, [hull], 1, cv.RGB(0, 255, 0), 4, cv.CV_AA) xmax, xmin, ymax, ymin = 0, w, 0, h for x, y in list(hull): xmax = max(xmax, x) ymax = max(ymax, y) xmin = min(xmin, x) ymin = min(ymin, y) cv.Rectangle(im_cv_c, (xmin, ymin), (xmax, ymax), cv.RGB(0, 255, 255), 4) height = (ymax - ymin) width = (xmax - xmin) if width > MAX_WIDTH or width < MIN_WIDTH: contours = contours.h_next() continue diff = cv.MatchShapes(contours, TEMPLATE_CONTOURS, cv.CV_CONTOURS_MATCH_I3) if diff < EPSILON: cv.DrawContours(im_cv_c, contours, (255, 0, 0), (255, 0, 0), 0, -1) if not biggestCircle: biggestCircle = xmin, ymin, width, height BC_cnt = contours else: if width > biggestCircle[2]: biggestCircle = xmin, ymin, width, height BC_cnt = contours contours = contours.h_next() if biggestCircle: cv.DrawContours(im_cv_c, BC_cnt, (255, 0, 255), (255, 0, 255), 0, -1) cv.SaveImage('contours/' + name, im_cv_c) return cut_it_out(image, *biggestCircle, name=name) #cv.SaveImage('contours/' + name, im_cv_c) #cv2.imwrite('gray/' + name, image_processed_color) cv.SaveImage('contours/' + name, im_cv_c) return None, None
def getBinaryImageRGB(frame, rgbMin, rgbMax): resImg = cv.CreateImage(cv.GetSize(frame), 8, 1) cv.InRangeS(frame, rgbMin, rgbMax, resImg) cv.Not(resImg, resImg) return (resImg)