def warpimg(self, dstimg, symbol): dh,dw,dd = dstimg.shape self.dminx = dw self.dmaxx = 0 self.dminy = dh self.dmaxy = 0 for pt in symbol.location: if pt[0] > self.dmaxx: self.dmaxx = pt[0] if pt[0] < self.dminx: self.dminx = pt[0] if pt[1] > self.dmaxy: self.dmaxy = pt[1] if pt[1] < self.dminy: self.dminy = pt[1] dsize = (self.dmaxx-self.dminx, self.dmaxy-self.dminy) pts1 = numpy.float32([[0,0],[0,self.height],[self.width,self.height],[self.width,0]]) p0 = [symbol.location[0][0]-self.dminx, symbol.location[0][1]-self.dminy] p1 = [symbol.location[1][0]-self.dminx, symbol.location[1][1]-self.dminy] p2 = [symbol.location[2][0]-self.dminx, symbol.location[2][1]-self.dminy] p3 = [symbol.location[3][0]-self.dminx, symbol.location[3][1]-self.dminy] pts2 = numpy.float32([p0, p1, p2, p3]) M = cv2.getPerspectiveTransform(pts1,pts2) # Get the destination for the warp from the output image. # This is how transparency is done without alpha channel support. self.warp = dstimg[self.dminy:self.dmaxy, self.dminx:self.dmaxx] self.wh, self.ww, self.wd = self.warp.shape cv2.warpPerspective(self.img, M, dsize, dst=self.warp, borderMode=cv2.BORDER_TRANSPARENT)
def f2f(bg, curr, bgMask): sift = cv2.SIFT(nOctaveLayers=3, contrastThreshold=0.05, edgeThreshold=10) prev = bg.toImg() N, M, _ = prev.shape kp1, des1 = sift.detectAndCompute(prev, bgMask) kp2, des2 = sift.detectAndCompute(curr, None) FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) good = [] for m, n in matches: if m.distance < 0.75 * n.distance: good.append(m) if len(good) > 10: src_pts = np.float32( [kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2) dst_pts = np.float32( [kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2) H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 7.0) print H print len(kp1), len(kp2), len(good) img4 = cv2.warpPerspective(curr, H, (M, N), flags=cv2.WARP_INVERSE_MAP) mask4 = cv2.warpPerspective(np.zeros((720,1280), dtype=np.uint8), H, (M, N), flags=cv2.WARP_INVERSE_MAP, borderValue=255) mask4 = cv2.bitwise_not(mask4) bg.add(img4, mask4) cv2.bitwise_or(bgMask, mask4, dst=bgMask) return H
def actual_width_in_mm(lb, lt, rb, rt, cxr, cxl): """ * Function Name:actual_width_in_mm() * Input: co-ordinates of left bottom, left top, right bottom, right top, right contour centroid, left contour centroid * Output: returns actual width of the door * Logic: It takes the actual depth and using filters the black noise spaces are made white The 20 pixels of the area of left and right edges are processed. the minimum value in them is found and the depth is that value. Using pixel knowledge we find the angle and then using cosine rule we find the actual width of the door. * Example Call: actual_width_in_mm(lb, lt, rb, rt, cxr, cxl) """ a = freenect.sync_get_depth(format=freenect.DEPTH_MM)[0] a /= 30.0 a = a.astype(np.uint8) ret, mask = cv2.threshold(a, 1, 255, cv2.THRESH_BINARY_INV) ad = a + mask pts1 = np.float32([[lt[0] - 30, lt[1]], [lt[0], lt[1]], [lb[0] - 30, lb[1]], [lb[0], lb[1]]]) pts2 = np.float32([[0, 0], [30, 0], [0, lb[1] - lt[1]], [30, lb[1] - lt[1]]]) m = cv2.getPerspectiveTransform(pts1, pts2) dst = cv2.warpPerspective(ad, m, (30, lb[1] - lt[1])) left_depth = np.amin(dst) * 30 pts1 = np.float32([[rt[0], rt[1]], [rt[0] + 30, rt[1]], [rb[0], rb[1]], [rb[0] + 30, rb[1]]]) pts2 = np.float32([[0, 0], [30, 0], [0, rb[1] - rt[1]], [30, rb[1] - rt[1]]]) m = cv2.getPerspectiveTransform(pts1, pts2) dst = cv2.warpPerspective(ad, m, (30, rb[1] - rt[1])) right_depth = np.amin(dst) * 30 pixel_width = cxr - cxl angle = (pixel_width / 640.0) * (57 / 180.0) * math.pi width = (left_depth * left_depth) + (right_depth * right_depth) - (2 * left_depth * right_depth * math.cos(angle)) width = math.sqrt(width) return width
def alignAndMakeMask(img1, img2): #get points from first image e1 = cvk2.RectWidget('ellipse') getPoints(e1, 'im1points.txt', img1) #get points from second image e2 = cvk2.RectWidget('ellipse') getPoints(e2, 'im2points.txt', img2) mask = makeMask(img2, e2) h2 = img2.shape[0] w2 = img2.shape[1] #use points to find homography between the images Hbig = cv2.findHomography(e1.points, e2.points, 0, 5) H = Hbig[0] dims = (w2, h2) white_image = numpy.zeros((h2, w2, 3), numpy.uint8) white_image[:,:,:] = 255 warped1 = numpy.zeros((h2, w2, 3), numpy.uint8) cv2.warpPerspective(img1, H, dims, warped1, borderMode=cv2.BORDER_TRANSPARENT) # cv2.imshow('window', warped1) # while cv2.waitKey(5) < 0: pass # cv2.imshow('window', img2) # while cv2.waitKey(5) < 0: pass return warped1, mask
def forward(self, inputs, outputs): """The forward operator. Reads from inputs and writes to outputs. """ if self.implementation == Impl['halide']: # Halide implementation tmpin = np.asfortranarray(inputs[0].astype(np.float32)) Halide('A_warp.cpp').A_warp(tmpin, self.Hinvf, self.tmpfwd) # Call np.copyto(outputs[0], np.reshape(self.tmpfwd, self.shape)) else: # CV2 version inimg = inputs[0] if len(self.H.shape) == 2: warpedInput = cv2.warpPerspective(np.asfortranarray(inimg), self.H.T, inimg.shape[1::-1], flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0.) # Necessary due to array layout in opencv np.copyto(outputs[0], warpedInput) else: for j in range(self.H.shape[2]): warpedInput = cv2.warpPerspective(np.asfortranarray(inimg), self.H[:, :, j].T, inimg.shape[1::-1], flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0.) # Necessary due to array layout in opencv np.copyto(outputs[0][:, :, :, j], warpedInput)
def adjoint(self, inputs, outputs): """The adjoint operator. Reads from inputs and writes to outputs. """ if self.implementation == Impl['halide'] : #Halide implementation if len(self.H.shape) == 2: tmpin = np.asfortranarray( inputs[0][..., np.newaxis].astype(np.float32) ) else: tmpin = np.asfortranarray( inputs[0].astype(np.float32) ) Halide('At_warp.cpp').At_warp( tmpin, self.Hf, self.tmpadj ) #Call np.copyto(outputs[0], self.tmpadj ) else: #CV2 version inimg = inputs[0] if len(self.H.shape) == 2: # + cv2.WARP_INVERSE_MAP warpedInput = cv2.warpPerspective(np.asfortranarray(inimg), self.Hinv.T, inimg.shape[1::-1], flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0.) np.copyto( outputs[0], warpedInput ) else: outputs[0][:] = 0.0 for j in range(self.H.shape[2]): warpedInput = cv2.warpPerspective(np.asfortranarray(inimg[:,:,:,j]), self.Hinv[:,:,j].T, inimg.shape[1::-1], flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0.) #Necessary due to array layout in opencv outputs[0] += warpedInput
def merge_images(image1, image2, homography, size, offset, keypoints): ## TODO: Combine the two images into one. ## TODO: (Overwrite the following 5 lines with your answer.) (h1, w1) = image1.shape[:2] (h2, w2) = image2.shape[:2] panorama = np.zeros((size[1], size[0], 3), np.uint8) (ox, oy) = offset translation = np.matrix([ [1.0, 0.0, ox], [0, 1.0, oy], [0.0, 0.0, 1.0] ]) if DEBUG: print homography homography = translation * homography # print homography # draw the transformed image2 cv2.warpPerspective(image2, homography, size, panorama) #panorama[oy:h1+oy, ox:ox+w1] = image1 for y in range(h1): for x in range(w1): if image1[y][x][0] < 25 and image1[y][x][1] < 25 and image1[y][x][0] < 25: continue panorama[oy+y][ox+x] = image1[y][x] # panorama[:h1, :w1] = image1 return panorama
def Bonus_perspective_warping(img1, img2, img3): # Write your codes here img1 = cv2.copyMakeBorder(img1, 200, 200, 500, 500, cv2.BORDER_CONSTANT) (M, pts1, pts2, mask) = getTransform(img2, img1, method='homography') # then transform im1 with the 3x3 transformation matrix out2 = cv2.warpPerspective(img2, M, (img1.shape[1], img1.shape[0])) # mask to blend the first 2 images mask = np.zeros_like(img1, dtype='float32') mask[:, int(img1.shape[1] * 0.55):] = 1 out2 = Laplacian_Pyramid_Blending_with_mask(out2, img1, mask, 3) (M, pts1, pts2, mask) = getTransform(img3, img1, method='homography') # then transform im1 with the 3x3 transformation matrix out3 = cv2.warpPerspective(img3, M, (img1.shape[1], img1.shape[0])) # mask to blend the last image with the interim output mask = np.zeros_like(img1, dtype='float32') mask[:, int(img1.shape[1] * 0.45):] = 1 out = Laplacian_Pyramid_Blending_with_mask(out2, out3, mask, 3) output_image = out # This is dummy output, change it to your output # Write out the result output_name = sys.argv[5] + "output_homography_lpb.png" cv2.imwrite(output_name, output_image) return True
def rectify_side_sample_projection(self, image, quad,segment_length, dest_raster): #opencv requires x,y coordinates whereas we're getting y,x #flip them quad_flipped = np.fliplr(quad) # points in the rectified sample's window rectified_pts = np.array([[0, self._crossbar_range - 1], [segment_length - 1, self._crossbar_range - 1], [segment_length - 1, 0], [0, 0]], dtype=np.float32) #obtain the transform transform = cv2.getPerspectiveTransform(quad_flipped.astype(np.float32), rectified_pts) #we can't use the return value here, as it will re-initialize the output array, #whereas we need to use the existing slice cv2.warpPerspective(image, transform, (dest_raster.shape[1], dest_raster.shape[0]), dst=dest_raster) if self._display_sample_areas: draw_quad(quad_flipped, self._display_image) #display the sub-sample if need be if self._display_subsamples: original, transformed = draw_seg_sample(image,segment_length, self._crossbar_range, dest_raster, rectified_pts, quad,factor=self.parent.display_scale_factor * 2) self.parent.imshow("Original Subsample",original, wait=False) ch = self.parent.imshow("Modified Subsample",transformed, wait=True) if ch == ascii.CODE.ESC: #the user chooses to stop viewing subsamples during this run self._display_subsamples = False
def textureMapFace(image,face,faceJPG,cam2,x,y): texture_image = cv2.imread('Images/'+faceJPG) h,w,d = shape(texture_image) # find the corners of the texture texture_corners=np.array([[0.,0.],[float(w),0.],[float(w),float(h)],[0.,float(h)]]) # find the corners of the projective face using the camera matrix # split to individual points, homogenize them, project them, un-homogenize the projected points projected_corners=[] for i in range(4): # split and homogenize corner = hstack((face.T[i],1)) # project projected_corner = cam2.project(np.matrix(corner).T) # un-homogenize projected_corners.append(projected_corner[:2]) projected_corners=np.array(projected_corners) H=estimateHomography(texture_corners,projected_corners) texture = cv2.warpPerspective(texture_image,H,(x,y)) # black image with projected face white_image = cv2.imread('Images/white.jpg') Mask = cv2.warpPerspective(white_image,H,(x,y)) # black image with white face Mask=cv2.bitwise_not(Mask) # white image with black face I1=cv2.bitwise_and(Mask,image) # image background with black face image=cv2.bitwise_or(I1,texture) # image background with texture image face #overlay = cv2.warpPerspective(texture_image,H,(x,y)) #image=cv2.addWeighted(image,0.5,overlay,0.5,0) return image
def Bonus_perspective_warping(img1, img2, img3): # Write your codes here img1 = cv2.copyMakeBorder(img1, 200, 200, 500, 500, cv2.BORDER_CONSTANT) (M, pts1, pts2, mask) = getTransform(img2, img1, method='homography') # then transform im1 with the 3x3 transformation matrix out = cv2.warpPerspective(img2, M, (img1.shape[1], img1.shape[0])) # dst=img1.copy(), # borderMode=cv2.BORDER_TRANSPARENT) out = Laplacian_Pyramid_Blending_with_mask(img1, img2, mask) img1 = out (M, pts1, pts2, mask) = getTransform(img3, img1, method='homography') # then transform im1 with the 3x3 transformation matrix # out = Laplacian_Pyramid_Blending_with_mask(img1, img3, mask) out = cv2.warpPerspective(img3, M, (img1.shape[1], img1.shape[0])) # dst=img1.copy(), # borderMode=cv2.BORDER_TRANSPARENT) mask = np.zeros_like(img1, dtype='float32') out = Laplacian_Pyramid_Blending_with_mask(img1, img3, mask) plt.imshow(out, cmap='gray') plt.show() output_image = out # This is dummy output, change it to your output print RMSD(1, out, cv2.imread("./example_output1.png", 0)) output_image = img1 # This is dummy output, change it to your output # Write out the result output_name = sys.argv[5] + "output_homography_lpb.png" cv2.imwrite(output_name, output_image) return True
def merge_images(image1, image2, homography, size, offset, keypoints): (h1, w1) = image1.shape[:2] (h2, w2) = image2.shape[:2] panorama = np.zeros((size[1], size[0], 3), np.uint8) (ox, oy) = offset translation = np.matrix([ [1.0, 0.0, ox], [0, 1.0, oy], [0.0, 0.0, 1.0] ]) homography = translation * homography # draw the transformed image2 cv2.warpPerspective(image2, homography, size, panorama) panorama[oy:h1+oy, ox:ox+w1] = image1 #crop panorama -- remove this for vertical images like 'door' test set height, width = panorama.shape[:2] crop_h = int(0.05 * height) crop_w = int(0.015 * width) panorama = panorama[crop_h:-crop_h, crop_w:-crop_w] panorama = panorama[int(oy*0.7):,:] #blend panorama = blend(panorama,image1,image2,ox,oy) return panorama
def test_homography(self): """Checks that a known homography is recovered accurately.""" # Load the left_houses image. houses_left = cv2.imread("test_data/houses_left.png", cv2.CV_LOAD_IMAGE_GRAYSCALE) rows, cols = houses_left.shape # Warp with a known homography. H_expected = self._known_homography(rows, cols) houses_left_warped = cv2.warpPerspective(houses_left, H_expected, (cols, rows)) # Compute the homography with the library. H_actual = pano_stitcher.homography(houses_left_warped, houses_left) houses_left_warped = cv2.warpPerspective(houses_left, H_actual, (cols, rows)) # The two should be nearly equal. H_difference = numpy.absolute(H_expected - H_actual) H_difference_magnitude = numpy.linalg.norm(H_difference) print "Expected homography:" print H_expected print "Actual homography:" print H_actual print "Difference:" print H_difference print "Magnitude of difference:", H_difference_magnitude max_difference_magnitude = 0.5 self.assertLessEqual(H_difference_magnitude, max_difference_magnitude)
def Video_filter(cap,i ): # Capture frame-by-frame ret, frame = cap.read() if(i==2):# bottom camera ch = frame.shape pts1 = np.float32([[112,275],[637,284],[149,345],[587,357]]) pts2 = np.float32([[0,0],[484,0],[0,162],[484,162]]) M = cv2.getPerspectiveTransform(pts1,pts2) frame = cv2.warpPerspective(frame,M,(484,162)) elif(i==1):#t0p camera ch = frame.shape pts1 = np.float32([[2,242],[610,260],[58,258],[490,274]]) pts2 = np.float32([[0,0],[484,0],[0,20],[484,20]]) M = cv2.getPerspectiveTransform(pts1,pts2) frame= cv2.warpPerspective(frame,M,(484,20)) cv2.imwrite('frame.jpg',frame) hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_blue = np.array([0, 30, 60]) upper_blue = np.array([20, 150, 255]) mask = cv2.inRange(hsv, lower_blue, upper_blue) kernel = np.ones((7,7),np.uint8) erosion = cv2.dilate(mask,kernel,iterations = 2) dilation = cv2.erode(erosion,kernel,iterations = 2) ret3,th3 = cv2.threshold(dilation,100,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) edges = cv2.Canny(th3,150,255) cv2.imshow('edge%d'%i,edges) cv2.imshow('colour%d'%i,frame) return edges
def build(): parser = argparse.ArgumentParser() parser.add_argument("file", help="input file") parser.parse_args() cap = cv2.VideoCapture(parser.parse_args().file) num = 1 n = 0 scale = 1 for _ in range(10): ret, iframe = cap.read() M, N = int(1280 * scale), int(720 * scale) initM = np.array([[1.0, 0, 1], [0, 1.0, 1], [0, 0, 1.0]]) initF = cv2.warpPerspective(iframe, initM, (M, N)) mask = cv2.warpPerspective(np.zeros((720, 1280), dtype=np.uint8), initM, (M, N), borderValue=255) mask = cv2.bitwise_not(mask) bg = SBG(initF, mask) while cap.isOpened(): ret, frame = cap.read() if not ret: break if num % 10 == 0: f2f(bg, frame, mask) fastFeature(bg, frame, mask) cv2.imshow("bg", bg.toImg()) cv2.imshow("frame", frame) if cv2.waitKey(50) & 0xFF == ord("q"): break num += 1
def stitch(img1, img2): MIN_MATCH_COUNT = 10 # Initiate SIFT detector sift = cv2.SIFT() # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) flann_matcher = get_matcher() matches = flann_matcher.knnMatch(des1, des2, k=2) # store all the good matches as per Lowe's ratio test. good = [] for m,n in matches: if m.distance < 0.7*n.distance: good.append(m) if len(good)>MIN_MATCH_COUNT: src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) H, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0) (o_size, offset) = calc_size(img1.shape, img2.shape, H) (o_size, offset) = calc_size(img1.shape, img2.shape, H) # y dst_h = o_size[0] # x dst_w = o_size[1] offset_h = np.matrix(np.identity(3), np.float32) offset_h[0,2] = offset[0] offset_h[1,2] = offset[1] warped_1 = cv2.warpPerspective( img1, offset_h, (dst_w, dst_h) ) warped_2 = cv2.warpPerspective( img2, H, (dst_w, dst_h) ) out = np.zeros((dst_h, dst_w), np.uint8) out = cv2.add(out, warped_1, dtype=cv2.CV_8U) out = cv2.add(out, warped_2, dtype=cv2.CV_8U) return out else: print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT) matchesMask = None
def merge_images(image1, image2, homography, size, offset, keypoints): ## Combine the two images into one. (h1, w1) = image1.shape[:2] (h2, w2) = image2.shape[:2] panorama = np.zeros((size[1], size[0], 3), np.uint8) (ox, oy) = offset translation = np.matrix([[1.0, 0.0, ox], [0, 1.0, oy], [0.0, 0.0, 1.0]]) if DEBUG: print homography homography = translation * homography # print homography # draw the transformed image2 cv2.warpPerspective(image2, homography, size, panorama) panorama[oy : h1 + oy, ox : ox + w1] = image1 # panorama[:h1, :w1] = image1 return panorama
def Perspective_warping(img1, img2, img3): img1 = cv2.copyMakeBorder(img1, 200, 200, 500, 500, cv2.BORDER_CONSTANT) (M, pts1, pts2, mask) = getTransform(img2, img1, method='homography') # then transform im1 with the 3x3 transformation matrix out = cv2.warpPerspective( img2, M, (img1.shape[1], img1.shape[0]), dst=img1.copy(), borderMode=cv2.BORDER_TRANSPARENT) img1 = out (M, pts1, pts2, mask) = getTransform(img3, img1, method='homography') # then transform im1 with the 3x3 transformation matrix out = cv2.warpPerspective( img3, M, (img1.shape[1], img1.shape[0]), dst=img1.copy(), borderMode=cv2.BORDER_TRANSPARENT) output_image = out # This is dummy output, change it to your output # Write out the result output_name = sys.argv[5] + "output_homography.png" cv2.imwrite(output_name, output_image) return True
def faceSwapImages(im1): im1 = ensureImageLessThanMax(im1) im1_all_landmarks = get_landmarks(im1) im1 = im1.astype(numpy.float64) for im1_face_landmarks in im1_all_landmarks: im2_direction, im2,im2_landmarks,im2_flipped,im2_landmarks_flipped = random.choice(FACESWAPS) #swap the face if theyre pointing the wrong direction im1_direction = getFaceDirection(im1_face_landmarks) if im2_direction != im1_direction: im2 = im2_flipped im2_landmarks = im2_landmarks_flipped M = transformation_from_points(im2_landmarks[ALIGN_POINTS], im1_face_landmarks[ALIGN_POINTS]) mask = get_face_mask(im2, im2_landmarks) warped_mask = cv2.warpPerspective(mask, M, (im1.shape[1], im1.shape[0])) combined_mask = cv2.max(get_face_mask(im1, im1_face_landmarks), warped_mask) #warp onto im1 to try and reduce any color correction issues around the edge of im2 warped_im2 = cv2.warpPerspective(im2, M, (im1.shape[1], im1.shape[0]), dst=im1.copy(), borderMode=cv2.BORDER_TRANSPARENT) warped_corrected_im2 = correct_colours(im1, warped_im2, im1_face_landmarks) im1 = im1 * (1.0 - combined_mask) + warped_corrected_im2 * combined_mask im1 = numpy.clip(im1, 0, 255, out=im1).astype(numpy.uint8) return im1
def detect_cards(im, numcontures = 10): origin = im contours = find_contures(im, numcontures) warps = [] diffs = [] for card in contours: peri = cv2.arcLength(card,True) conture = cv2.approxPolyDP(card,0.02*peri,True) if len(conture) != 4: continue approx = rectify(conture) cnt = card[4] cv2.drawContours(origin, card, 0, (0, 255, 255), 5) # show_image(origin, "card") h_vertical = np.array([ [0,0],[im_width,0], [im_width,im_height],[0,im_height] ], np.float32) h_horizontal = np.array([ [0,im_height], [0,0], [im_width,0],[im_width,im_height] ], np.float32) transform = cv2.getPerspectiveTransform(approx,h_vertical) warp = cv2.warpPerspective(im,transform,(im_width,im_height)) show_image(warp, "vertical") in_database(warp, diffs, card, transform) transform = cv2.getPerspectiveTransform(approx,h_horizontal) warp = cv2.warpPerspective(im,transform,(im_width,im_height)) #show_image(warp, "horizontal") #in_database(warp, diffs, card) return diffs
def mergeImages(img1, img2, AlignMethod='', Jacobian='', **kwargs): (kp1Matches, kp2Matches) = Alignment2D.ExtractFeatures(img1, img2, **kwargs) Transform = Alignment2D.AlignImages(kp1Matches, kp2Matches, AlignMethod, Jacobian) #Overlay the two images, showing the detected feature. rows,cols,colours = img1.shape Canvas1 = np.zeros((rows * 2, cols * 2, colours) , img1.dtype) Canvas2 = np.copy(Canvas1) finalRows, finalCols, colours = Canvas1.shape tx = cols/2; # Translate to the center of the canvas ty = rows/2; M = np.float32([[1,0,tx],[0,1,ty],[0,0,1]]) img3 = cv2.drawKeypoints(img1, kp1Matches,color=(0,0,255)) cv2.warpPerspective(img3, M, (finalCols, finalRows), Canvas1) finalTransform = np.dot(M, Transform) ; # Translate to the center of the canvas img2 = cv2.drawKeypoints(img2, kp2Matches,color=(255,0,0)) cv2.warpPerspective(img2, finalTransform, (finalCols, finalRows), Canvas2, borderMode=cv2.BORDER_TRANSPARENT) alpha = 0.5 beta = (1.0 - alpha) cv2.addWeighted(Canvas1, alpha, Canvas2, beta, 0.0, Canvas1) return Canvas1
def dispImages(img): if CALC_TRANSFORM: (found, corners) = cv2.findChessboardCorners( img, boardSize, flags = cv2.CALIB_CB_ADAPTIVE_THRESH | cv2.CALIB_CB_FAST_CHECK | \ cv2.CALIB_CB_NORMALIZE_IMAGE ) if not found: rospy.loginfo("ERROR: cannot find chess board in image") return; transform = calcTransform(img, corners, boardSize) print transform transformed = cv2.warpPerspective(img, transform, (img.shape[1],img.shape[0])) cv2.drawChessboardCorners(img, boardSize, corners, found) else: global prev_transform transformed = cv2.warpPerspective(img, prev_transform, (img.shape[1], img.shape[0])) cv2.imshow('Transformed', transformed) cv2.imshow('Plain', img) cv2.imwrite('plain.png', img) cv2.imwrite('transformed.png', transformed)
def merge_images(image1, image2, homography, size, offset, keypoints): ## TODO: Combine the two images into one. ## TODO: (Overwrite the following 5 lines with your answer.) (h1, w1) = image1.shape[:2] (h2, w2) = image2.shape[:2] panorama = np.zeros((size[1], size[0], 3), np.uint8) (ox, oy) = offset translation = np.matrix([ [1.0, 0.0, ox], [0, 1.0, oy], [0.0, 0.0, 1.0] ]) if DEBUG: print homography homography = translation * homography # print homography # draw the transformed image2 cv2.warpPerspective(image2, homography, size, panorama) panorama[oy:h1+oy, ox:ox+w1] = image1 # panorama[:h1, :w1] = image1 ## TODO: Draw the common feature keypoints. return panorama
def addTexMask(img, tex, Face, camera): ITop = tex white = np.copy(ITop) white[:, :] = [255, 255, 255] mTop, nTop, i = shape(ITop) topTexPoints = [(0, 0), (0, nTop), (mTop, nTop), (mTop, 0)] side_cam = np.array(camera.project(toHomogenious(Face))) # toppen sideCam = [ (int(side_cam[0][0]), int(side_cam[1][0])), (int(side_cam[0][1]), int(side_cam[1][1])), (int(side_cam[0][2]), int(side_cam[1][2])), (int(side_cam[0][3]), int(side_cam[1][3])), ] # making a H between texture and side of cube H = estimateHomography(topTexPoints, sideCam) m, n, d = shape(img) overlay = cv2.warpPerspective(white, H, (n, m)) texWarped = cv2.warpPerspective(ITop, H, (n, m)) Mask = cv2.threshold(overlay, 1, 255, cv2.THRESH_BINARY)[1] backGr = 255 - Mask I1 = cv2.bitwise_and(backGr, img) img = cv2.bitwise_or(I1, texWarped) return img
def get_cropped_image(self, rect, image, mask): """ Tries to crop the table from image and warps its perspective so we can get table image as if we are standing in front of it Args: rect(numpy.ndarray): Contures of a board image(numpy.ndarray): Image to shift and crop from mask(numpy.ndarray): Mask to shift Returns: Shifted perspective of croped table and its mask for further processing and checking. """ (tl, tr, br, bl) = rect width_a = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2)) width_b = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2)) height_a = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2)) height_b = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2)) max_width = max(int(width_a), int(width_b)) max_height = max(int(height_a), int(height_b)) dst = np.array([ [0, 0], [max_width - 1, 0], [max_width - 1, max_height - 1], [0, max_height - 1]], dtype="float32") warp_mat = cv.getPerspectiveTransform(rect, dst) warp = cv.warpPerspective(image, warp_mat, (max_width, max_height)) warp_mask = cv.warpPerspective(mask, warp_mat, (max_width, max_height)) return (warp, warp_mask)
def do_shift_scale_rotate2( image, mask, dx=0, dy=0, scale=1, angle=0 ): borderMode=cv2.BORDER_REPLICATE #cv2.BORDER_REFLECT_101 cv2.BORDER_CONSTANT height, width = image.shape[:2] sx = scale sy = scale cc = math.cos(angle/180*math.pi)*(sx) ss = math.sin(angle/180*math.pi)*(sy) rotate_matrix = np.array([ [cc,-ss], [ss,cc] ]) box0 = np.array([ [0,0], [width,0], [width,height], [0,height], ],np.float32) box1 = box0 - np.array([width/2,height/2]) box1 = np.dot(box1,rotate_matrix.T) + np.array([width/2+dx,height/2+dy]) box0 = box0.astype(np.float32) box1 = box1.astype(np.float32) mat = cv2.getPerspectiveTransform(box0,box1) image = cv2.warpPerspective(image, mat, (width,height),flags=cv2.INTER_LINEAR, borderMode=borderMode,borderValue=(0,0,0,)) #cv2.BORDER_CONSTANT, borderValue = (0, 0, 0)) #cv2.BORDER_REFLECT_101 mask = cv2.warpPerspective(mask, mat, (width,height),flags=cv2.INTER_NEAREST,#cv2.INTER_LINEAR borderMode=borderMode,borderValue=(0,0,0,)) #cv2.BORDER_CONSTANT, borderValue = (0, 0, 0)) #cv2.BORDER_REFLECT_101 mask = (mask>0.5).astype(np.float32) return image, mask
def add_substitute_quad(image, substitute_quad, dst): # dst (zero-set) and src points dst = order_points(dst) if dst.shape[0] < 4: return (tl, tr, br, bl) = dst min_x = min(int(tl[0]), int(bl[0])) min_y = min(int(tl[1]), int(tr[1])) for point in dst: point[0] = point[0] - min_x point[1] = point[1] - min_y (max_width,max_height) = max_width_height(dst) src = topdown_points(max_width, max_height) # warp perspective (with white border) substitute_quad = cv2.resize(substitute_quad, (max_width,max_height)) warped = np.zeros((max_height,max_width, 3), np.uint8) warped[:,:,:] = 255 matrix = cv2.getPerspectiveTransform(src, dst) cv2.warpPerspective(substitute_quad, matrix, (max_width,max_height), warped, borderMode=cv2.BORDER_TRANSPARENT) # add substitute quad image[min_y:min_y + max_height, min_x:min_x + max_width] = warped return image
def ApplyTexture(self, image, filename, points): """Applies a texture mapping over an augmented virtual object.""" # Get the size of the analyzed image. h, w = image.shape[:2] # <031> Open the texture mapping image and get its size. textureMap = cv2.imread(filename) th, tw = textureMap.shape[:2] # Creates a mask with the same size of the input image. whiteMask = np.ones(textureMap.shape[:2], dtype=np.uint8) * 255 blackMask = np.zeros(image.shape[:2], dtype=np.uint8) # cv2.imshow("mask", whiteMask) # TODO: FINISH # <032> Estimate the homography matrix between the texture mapping and the cube face. # srcPts = np.float32([[0, 0], [tw, 0], [0, th], [tw, th]]) srcPts = np.float32([[0, th], [tw, th], [tw, 0], [0, 0]]) points = points.reshape(4,2) # print "appText:" # print "----------------------------" # print srcPts # print "----------------------------" # print points # print "----------------------------" H, _ = cv2.findHomography(srcPts, points) # <033> Applies a perspective transformation to the texture mapping image. textureWarped = cv2.warpPerspective(textureMap, H, (w, h)) whiteMask = cv2.warpPerspective(whiteMask, H, (w, h)) # tw = cv2.cvtColor(textureWarped, cv2.COLOR_BGR2GRAY) # blackMask = cv2.cvtColor(blackMask, cv2.COLOR_GRAY2BGR) # whiteMask = cv2.cvtColor(whiteMask, cv2.COLOR_GRAY2BGR) tw = textureWarped bin = cv2.bitwise_or(blackMask, whiteMask) # return tw, bin # bin = cv2.bitwise_or(blackMask, whiteMask) # ttw = cv2.bitwise_and(bin, tw) # tmpImg = cv2.bitwise_or(image, cv2.cvtColor(ttw, cv2.COLOR_GRAY2BGR)) # tmpImg = cv2.bitwise_or(image, tw) # tmpImg = cv2.bitwise_or(image, tw, mask = bin) # tmpImg2 = cv2.bitwise_or(tw, tmpImg) bin2 = cv2.bitwise_not(bin) tmpImg = cv2.bitwise_and(image, cv2.cvtColor(bin2, cv2.COLOR_GRAY2BGR)) return tw, bin
def transformCellMask(): global maskImg, maskImgUndefined points1 = np.array([[0, 0], [maskImg.shape[0], 0], [0, maskImg.shape[1]], [maskImg.shape[0], maskImg.shape[1]]], np.float32) points2 = np.array([[0, 0], [xStep, 0], [0, yStep], [xStep, yStep]], np.float32) (H, _) = cv2.findHomography(points1, points2) maskImg = cv2.warpPerspective(maskImg, H, (xStep, yStep)) maskImgUndefined = cv2.warpPerspective(maskImgUndefined, H, (xStep, yStep))
def warped_image_from_match(img1, img2, key1, key2, pairs, mask): "Warp the image based on RANSAC matching." p1 = np.array([key1[p1].pt for p1, _ in pairs]) p2 = np.array([key2[p2].pt for _, p2 in pairs]) val, trans = cv2.findHomography(p2, p1, cv2.RANSAC) return (cv2.warpPerspective(img2, val, (img1.shape[1], img1.shape[0])), \ cv2.warpPerspective(mask, val, (img1.shape[1], img1.shape[0])))
def frameDetection(self): """ The core method of the class. Use it to extract the frame in the image. The extracted frame is in grayscale. The followed steps are : 1. grayscale + smoothering + gamma to make the frame darker + binary threshold (rational = the frame is one of the darkest part in the picture). 2. extract regions of "interest". 3. heuristic to find a region of interest that is large enough, in the center of the picture and where length along x-axis > length along y-axis. 4. make a perspective transform to crop the image and deal with perspective deformations. """ self.image = imutils.resize(self.image, height=500) # Step 1: grayscale + smoothering + gamma to make the frame darker + binary threshold gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) gamma = frameExtractor.adjust_gamma(blurred, gamma=0.7) shapeMask = cv2.threshold(gamma, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] # Step 2: extract regions of "interest". label_image = label(shapeMask) Cnt = None position = [0, 0, 0, 0] for region in regionprops(label_image): # Step 3: heuristic to find a region large enough, in the center & with length along x-axis > length along y-axis. minr, minc, maxr, maxc = region.bbox c = np.array([[minc, minr], [minc, maxr], [maxc, minr], [maxc, maxr]]) if Cnt is None: Cnt = c position = [minr, minc, maxr, maxc] old_dist = self.distance_from_center(Cnt) new_dist = self.distance_from_center(c) Lx = maxc - minc Ly = maxr - minr c = frameExtractor.sort_pts_clockwise(c) if old_dist>new_dist and Ly<Lx and cv2.contourArea(c)>0.05*(shapeMask.shape[0]*shapeMask.shape[1]): displayCnt = c position = [minr, minc, maxr, maxc] Cnt = Cnt.reshape(4, 2) Cnt = frameExtractor.sort_pts_clockwise(Cnt) # Step 4: Make a perspective transform to crop the image and deal with perspective deformations. try: # Crop the image around the region of interest (but keep a bit of distance with a 30px padding). # Darken + Binary threshold + rectangle detection. # If this technique fails, raise an error and use basic methods (except part). crop_img = self.image[max(0, position[0] - 30):min(position[2] + 30, self.image.shape[0]),\ max(0, position[1] - 30):min(self.image.shape[1], position[3] + 30)] crop_blurred = cv2.GaussianBlur(crop_img, (5, 5), 0) crop_gamma = frameExtractor.adjust_gamma(crop_blurred, gamma=0.4) crop_gray = cv2.cvtColor(crop_gamma, cv2.COLOR_BGR2GRAY) crop_thresh = cv2.threshold(crop_gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] cnts = cv2.findContours(crop_thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if imutils.is_cv2() else cnts[1] cnts = sorted(cnts, key=cv2.contourArea, reverse=True) Cnt_bis = None for c in cnts: peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) if len(approx) == 4: Cnt_bis = approx break if cv2.contourArea(Cnt_bis)<0.5*(crop_img.shape[0]*crop_img.shape[1]): raise ValueError("Couldn't find the box, so switching to ad hoc method.") Cnt_bis = Cnt_bis.reshape(4, 2) Cnt_bis = frameExtractor.sort_pts_clockwise(Cnt_bis) src_pts = Cnt_bis.copy() src_pts = src_pts.astype(np.float32) dst_pts = np.array([[0, 0], [400, 0], [400, 100], [0, 100]], dtype=np.float32) dst_pts = dst_pts.astype(np.float32) persp = cv2.getPerspectiveTransform(src_pts, dst_pts) warped = cv2.warpPerspective(crop_img, persp, (400, 100)) except: # More basic techniques that give +/- acceptable results when the first technique fails. src_pts = Cnt.copy() src_pts = src_pts.astype(np.float32) dst_pts = np.array([[0, 0], [400, 0], [400, 100], [0, 100]], dtype=np.float32) dst_pts = dst_pts.astype(np.float32) persp = cv2.getPerspectiveTransform(src_pts, dst_pts) warped = cv2.warpPerspective(gray, persp, (400, 100)) # Frame is extracted from the initial image in grayscale (not other processing done on the image). self.raw_frame = warped
def Draw_triangle(self, contours, rgb, obj_desire): ################## DELAY = 0.02 USE_CAM = 1 IS_FOUND = 0 count = 0 #count feature tile numbers cnt = 0 central_list = [] uvuv = uv() tile_uv = tileuv() ################## _width = 480.0 _height = 640.0 _margin = 0.0 corners = np.array([ [[_margin, _margin]], [[_margin, _height + _margin]], [[_width + _margin, _height + _margin]], [[_width + _margin, _margin]], ]) pts_dst = np.array(corners, np.float32) latest_central = (0, 0) for cont in contours: resultuv = [] """ #1,num,2,centeral point 3,for angular point uv ,4,clockwise direction #caculating Area for tile selected just one tile """ # print "cont----------", cont # 获取轮廓长度 arc_len = cv2.arcLength(cont, True) # 多边形拟合 approx = cv2.approxPolyDP(cont, 0.1 * arc_len, True) # print "cv2.contourArea(cont)",cv2.contourArea(cont) # print "approx",len(np.array(approx).reshape(-1,2)) if cv2.contourArea(cont) > 3000 and cv2.contourArea(cont) < 8000: # if cv2.contourArea(cont) > 3000: if (len(approx) == 4): IS_FOUND = 1 M = cv2.moments(cont) # 获取图像质心坐标 cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) now_central = (cX, cY) if self.Judge_isnot_same_tile(latest_central, now_central) != 1: count += 1 cv2.putText(rgb, str(count), (cX, cY), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 3) print "CX,CY", [cX, cY] central_list.append([cX, cY]) pts_src = np.array(approx, np.float32) # print "pts_src", pts_src cv2.circle(rgb, (cX, cY), 5, (0, 0, 0), -1) # print approx.tolist() angular_point = [] new_approx = self.Sort_tile_feature(approx) for i in range(len(new_approx)): if i == 0: cv2.circle(rgb, (new_approx[i][0], new_approx[i][1]), 5, (20, 60, 220), -1) angular_point.append( [new_approx[i][0], new_approx[i][1]]) cv2.putText(rgb, str(i), (new_approx[i][0], new_approx[i][1]), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 0), 1) else: cv2.circle(rgb, (new_approx[i][0], new_approx[i][1]), 5, (0, 255, 0), -1) angular_point.append( [new_approx[i][0], new_approx[i][1]]) cv2.putText(rgb, str(i), (new_approx[i][0], new_approx[i][1]), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 0), 1) resultuv.append([[count], [cX, cY], angular_point]) # draw trangle in image h, status = cv2.findHomography(pts_src, pts_dst) out = cv2.warpPerspective(rgb, h, (int(_width + _margin * 2), int(_height + _margin * 2))) cv2.drawContours(rgb, [approx], -1, (0, 255, 255), 3) # cv2.drawContours(rgb, [approx], -1, (20*count, 255, 0), -1, cv2.LINE_AA) print "all info for tile------", resultuv print "Now tile id", count if count == 1: tile_uv.tile_id = count tile_uv.obj_desire = obj_desire tile_uv.cen_uv.uvinfo = [cX, cY] tile_uv.f1th_uv.uvinfo = angular_point[0] tile_uv.s2th_uv.uvinfo = angular_point[1] tile_uv.t3th_uv.uvinfo = angular_point[2] tile_uv.f4th_uv.uvinfo = angular_point[3] self.tile_pub.publish(tile_uv) latest_central = now_central else: pass # count += 1 # cnt += 11 return rgb.copy()
if __name__ == '__main__': template = cv.imread('images/template.png') template_new_mask = cv.imread('images/template_new_mask.png') masks = sorted(os.listdir('images/masks')) for img in sorted(os.listdir('images/plates_text')): # if os.path.exists('images/rendered_new/' + img): # continue # # print(img) text = img.split('.')[0][-9:] if text[-1] == '_': text = text[:6] + '_' + text[-3:-1] new_plate = gen_base(template.copy(), text) mask = cv.imread('images/masks/' + img.split('.')[0][:-10] + '.jpg') corners = find_corners.find_corners(mask) p_t = cv.getPerspectiveTransform( np.array(find_corners.corners_old, dtype='float32'), np.array(corners, dtype='float32')) transformed = cv.warpPerspective(new_plate, p_t, (mask.shape[1], mask.shape[0])) new_mask = cv.warpPerspective(template_new_mask, p_t, (mask.shape[1], mask.shape[0])) # xs = [int(c_i[0]) for c_i in corners] # ys = [int(c_i[1]) for c_i in corners] # cropped = transformed[min(ys):max(ys), min(xs):max(xs), :] cv.imwrite('images/rendered_new/' + img, transformed) cv.imwrite('images/new_masks/' + img, new_mask)
import cv2 import numpy as np # mouse callback function def print_coord(event,x,y,flags,param): if event == cv2.EVENT_LBUTTONDBLCLK: print x,y # Create a black image, a window and bind the function to window img = cv2.imread('img20170108-005145.jpg') cv2.namedWindow('image') cv2.setMouseCallback('image',print_coord) while(1): pts1 = np.float32([[298,215], [487,213], [296,365], [508,367]]) pts2 = np.float32([[0,0],[360,0],[0,300],[360,300]]) M = cv2.getPerspectiveTransform(pts1,pts2) dst = cv2.warpPerspective(img,M,(360,300)) cv2.imshow('image',dst) if cv2.waitKey(20) & 0xFF == 27: break cv2.imwrite('image.jpg',dst) cv2.destroyAllWindows()
def estimate_affine_ecc(im1, im2): # Read the images to be aligned # im1 = cv2.imread("image1.jpg") # im2 = cv2.imread("image2.jpg") # im2 = cv2.imread('../datasets/row_data/multispectral/fake_and_real_tomatoes_ms_31.png') # im1 = cv2.imread('../datasets/row_data/multispectral/fake_and_real_tomatoes_ms_17.png') im1_gray = cv2.cvtColor(np.asarray(im1), cv2.COLOR_RGB2GRAY) im2_gray = cv2.cvtColor(np.asarray(im2), cv2.COLOR_RGB2GRAY) # Convert images to grayscale # im1_gray = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY) # im2_gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY) # Find size of image1 im1_size = im1.shape # Define the motion model # warp_mode = cv2.MOTION_TRANSLATION warp_mode = cv2.MOTION_AFFINE # warp_mode = cv2.MOTION_EUCLIDEAN # Define 2x3 or 3x3 matrices and initialize the matrix to identity if warp_mode == cv2.MOTION_HOMOGRAPHY: warp_matrix = np.eye(3, 3, dtype=np.float32) else: warp_matrix = np.eye(2, 3, dtype=np.float32) # Specify the number of iterations. number_of_iterations = 5000 # Specify the threshold of the increment # in the correlation coefficient between two iterations termination_eps = 1e-10 # Define termination criteria criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, number_of_iterations, termination_eps) # Enhanced Correlation Coefficient (ECC) # Run the ECC algorithm. The results are stored in warp_matrix. start = time.time() (cc, warp_matrix) = cv2.findTransformECC(im1_gray, im2_gray, warp_matrix, warp_mode, criteria, None, 5) if warp_mode == cv2.MOTION_HOMOGRAPHY: # Use warpPerspective for Homography im2_aligned = cv2.warpPerspective( im2, warp_matrix, (im1_size[1], im1_size[0]), flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP) else: # Use warpAffine for Translation, Euclidean and Affine im2_aligned = cv2.warpAffine(im2, warp_matrix, (im1_size[1], im1_size[0]), flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP) end = time.time() print('Alignment time (s): ', end - start)
cv2.setTrackbarPos("X2", "xyPosition", 803) cv2.setTrackbarPos("Y2", "xyPosition", 0) cv2.setTrackbarPos("X3", "xyPosition", 26) cv2.setTrackbarPos("Y3", "xyPosition", 575) cv2.setTrackbarPos("X4", "xyPosition", 970) cv2.setTrackbarPos("Y4", "xyPosition", 575) cv2.circle(frame, (x1, y1), 5, (0, 0, 255), -1) cv2.circle(frame, (x2, y2), 5, (0, 0, 255), -1) cv2.circle(frame, (x3, y3), 5, (0, 0, 255), -1) cv2.circle(frame, (x4, y4), 5, (0, 0, 255), -1) pts1 = np.float32([[x1, y1], [x2, y2], [x3, y3], [x4, y4]]) pts2 = np.float32([[0, 0], [500, 0], [0, 500], [500, 500]]) matrix = cv2.getPerspectiveTransform(pts1, pts2) result = cv2.warpPerspective(frame, matrix, (500, 500)) # both = np.concatenate((frame, result), axis=1) # cv2.imshow('Frame', both) cv2.imshow("Frame", frame) cv2.imshow("Output", result) key = cv2.waitKey(1) if key == 27: break result_resize = rescale_result(result) if not ret: print("cannot capture the frame") exit()
rect[3] = ROIdimensions[np.argmax(diff)] (tl, tr, br, bl) = rect widthA = np.sqrt((tl[0] - tr[0])**2 + (tl[1] - tr[1])**2) widthB = np.sqrt((bl[0] - br[0])**2 + (bl[1] - br[1])**2) maxWidth = max(int(widthA), int(widthB)) heightA = np.sqrt((tl[0] - bl[0])**2 + (tl[1] - bl[1])**2) heightB = np.sqrt((tr[0] - br[0])**2 + (tr[1] - br[1])**2) maxHeight = max(int(heightA), int(heightB)) dst = np.array([[0, 0], [maxWidth - 1, 0], [maxWidth - 1, maxHeight - 1], [0, maxHeight - 1]], dtype="float32") transformMatrix = cv2.getPerspectiveTransform(rect, dst) scan = cv2.warpPerspective(orig, transformMatrix, (maxWidth, maxHeight)) cv2.imshow("Scaned", scan) cv2.imwrite("WarpPerspective.jpg", scan) cv2.waitKey(0) cv2.destroyAllWindows() scanGray = cv2.cvtColor(scan, cv2.COLOR_BGR2GRAY) cv2.imshow("scanGray", scanGray) cv2.waitKey(0) cv2.destroyAllWindows() thresh1 = cv2.adaptiveThreshold(scanGray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 199, 17) thresh2 = cv2.adaptiveThreshold(scanGray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 199, 17)
#WARP perspective to get the bird's eye view from slant img to straight image like the cards one shown below import cv2 import numpy as np img=cv2.imread("C:\\Users\\kunjeshparekh\\Desktop\\KP\\Opencv\\cards.png") #add image path in this with img name cv2.imshow("cardimg",img) cv2.waitKey(0) img=cv2.resize(img,(500,500)) cv2.imwrite("C:\\Users\\kunjeshparekh\\Desktop\\KP\\Opencv\\new.png",img) width,height=250,350 pts1=np.float32([[111,229],[287,200],[154,482],[385,430]]) #rop left,top right,bottom left,bottom right points in paint pts2=np.float32([[0,0],[width,0],[0,height],[width,height]]) #resultant img's height width matrix=cv2.getPerspectiveTransform(pts1,pts2) imgoutput=cv2.warpPerspective(img,matrix,(width,height)) cv2.imshow("op",imgoutput) cv2.waitKey(0) #Joining Images in horizontal & Vertical Stack import cv2 import numpy as np img=cv2.imread("C:\\Users\\kunjeshparekh\\Desktop\\KP\\Opencv\\cards.png") #add image path in this with img name horizontal_stk=np.hstack((img,img)) cv2.imshow("horizontal",horizontal_stk) cv2.waitKey(0) vertical_stk=np.vstack((img,img,img)) cv2.imshow("Vertical",vertical_stk) cv2.waitKey(0)
def apply_transform(img, M): col, row = img[:2] out_img = cv2.warpPerspective(img, M, (row, col)) return out_img
def perspectiveTransform(img, M): h, w = img.shape[:2] return cv2.warpPerspective(img, M, (w, h), flags=cv2.INTER_LINEAR)
def get_video(image): img_size = (image.shape[1], image.shape[0]) # Calibrate camera and undistort image ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size, None, None) undist = cv2.undistort(image, mtx, dist, None, mtx) # Perform perspective transform offset = 0 src = np.float32([[490, 482], [810, 482], [1250, 720], [0, 720]]) dst = np.float32([[0, 0], [1280, 0], [1250, 720], [40, 720]]) M = cv2.getPerspectiveTransform(src, dst) warped = cv2.warpPerspective(undist, M, img_size) # Generate binary thresholded images b_channel = cv2.cvtColor(warped, cv2.COLOR_RGB2Lab)[:, :, 2] l_channel = cv2.cvtColor(warped, cv2.COLOR_RGB2LUV)[:, :, 0] # Set the upper and lower thresholds for the b channel b_thresh_min = 145 b_thresh_max = 200 b_binary = np.zeros_like(b_channel) b_binary[(b_channel >= b_thresh_min) & (b_channel <= b_thresh_max)] = 1 # Set the upper and lower thresholds for the l channel l_thresh_min = 215 l_thresh_max = 255 l_binary = np.zeros_like(l_channel) l_binary[(l_channel >= l_thresh_min) & (l_channel <= l_thresh_max)] = 1 combined_binary = np.zeros_like(b_binary) combined_binary[(l_binary == 1) | (b_binary == 1)] = 1 # Identify all non zero pixels in the image x, y = np.nonzero(np.transpose(combined_binary)) if Left.found == True: # Search for left lane pixels around previous polynomial leftx, lefty, Left.found = Left.found_search(x, y) if Right.found == True: # Search for right lane pixels around previous polynomial rightx, righty, Right.found = Right.found_search(x, y) if Right.found == False: # Perform blind search for right lane lines rightx, righty, Right.found = Right.blind_search(x, y, combined_binary) if Left.found == False: # Perform blind search for left lane lines leftx, lefty, Left.found = Left.blind_search(x, y, combined_binary) lefty = np.array(lefty).astype(np.float32) leftx = np.array(leftx).astype(np.float32) righty = np.array(righty).astype(np.float32) rightx = np.array(rightx).astype(np.float32) # Calculate left polynomial fit based on detected pixels left_fit = np.polyfit(lefty, leftx, 2) # Calculate intercepts to extend the polynomial to the top and bottom of warped image leftx_int, left_top = Left.get_intercepts(left_fit) # Average intercepts across n frames Left.x_int.append(leftx_int) Left.top.append(left_top) leftx_int = np.mean(Left.x_int) left_top = np.mean(Left.top) Left.lastx_int = leftx_int Left.last_top = left_top # Add averaged intercepts to current x and y vals leftx = np.append(leftx, leftx_int) lefty = np.append(lefty, 720) leftx = np.append(leftx, left_top) lefty = np.append(lefty, 0) # Sort detected pixels based on the yvals leftx, lefty = Left.sort_vals(leftx, lefty) Left.X = leftx Left.Y = lefty # Recalculate polynomial with intercepts and average across n frames left_fit = np.polyfit(lefty, leftx, 2) Left.fit0.append(left_fit[0]) Left.fit1.append(left_fit[1]) Left.fit2.append(left_fit[2]) left_fit = [np.mean(Left.fit0), np.mean(Left.fit1), np.mean(Left.fit2)] # Fit polynomial to detected pixels left_fitx = left_fit[0] * lefty**2 + left_fit[1] * lefty + left_fit[2] Left.fitx = left_fitx # Calculate right polynomial fit based on detected pixels right_fit = np.polyfit(righty, rightx, 2) # Calculate intercepts to extend the polynomial to the top and bottom of warped image rightx_int, right_top = Right.get_intercepts(right_fit) # Average intercepts across 5 frames Right.x_int.append(rightx_int) rightx_int = np.mean(Right.x_int) Right.top.append(right_top) right_top = np.mean(Right.top) Right.lastx_int = rightx_int Right.last_top = right_top rightx = np.append(rightx, rightx_int) righty = np.append(righty, 720) rightx = np.append(rightx, right_top) righty = np.append(righty, 0) # Sort right lane pixels rightx, righty = Right.sort_vals(rightx, righty) Right.X = rightx Right.Y = righty # Recalculate polynomial with intercepts and average across n frames right_fit = np.polyfit(righty, rightx, 2) Right.fit0.append(right_fit[0]) Right.fit1.append(right_fit[1]) Right.fit2.append(right_fit[2]) right_fit = [np.mean(Right.fit0), np.mean(Right.fit1), np.mean(Right.fit2)] # Fit polynomial to detected pixels right_fitx = right_fit[0] * righty**2 + right_fit[1] * righty + right_fit[2] Right.fitx = right_fitx # Compute radius of curvature for each lane in meters left_curverad = Left.radius_of_curvature(leftx, lefty) right_curverad = Right.radius_of_curvature(rightx, righty) # Only print the radius of curvature every 3 frames for improved readability if Left.count % 3 == 0: Left.radius = left_curverad Right.radius = right_curverad # Calculate the vehicle position relative to the center of the lane position = (rightx_int + leftx_int) / 2 distance_from_center = abs((640 - position) * 3.7 / 700) Minv = cv2.getPerspectiveTransform(dst, src) warp_zero = np.zeros_like(combined_binary).astype(np.uint8) color_warp = np.dstack((warp_zero, warp_zero, warp_zero)) pts_left = np.array( [np.flipud(np.transpose(np.vstack([Left.fitx, Left.Y])))]) pts_right = np.array([np.transpose(np.vstack([right_fitx, Right.Y]))]) pts = np.hstack((pts_left, pts_right)) cv2.polylines(color_warp, np.int_([pts]), isClosed=False, color=(0, 0, 255), thickness=40) cv2.fillPoly(color_warp, np.int_(pts), (34, 255, 34)) newwarp = cv2.warpPerspective(color_warp, Minv, (image.shape[1], image.shape[0])) result = cv2.addWeighted(undist, 1, newwarp, 0.5, 0) # Print distance from center on video if position > 640: cv2.putText( result, 'Vehicle is {:.2f}m left of center'.format(distance_from_center), (100, 80), fontFace=16, fontScale=2, color=(255, 255, 255), thickness=2) else: cv2.putText( result, 'Vehicle is {:.2f}m right of center'.format(distance_from_center), (100, 80), fontFace=16, fontScale=2, color=(255, 255, 255), thickness=2) # Print radius of curvature on video cv2.putText(result, 'Radius of Curvature {}(m)'.format( int((Left.radius + Right.radius) / 2)), (120, 140), fontFace=16, fontScale=2, color=(255, 255, 255), thickness=2) Left.count += 1 return result
def fit_polynomial(image): combined_binary = apply_thresholds(image, show=False) rightx = [] righty = [] leftx = [] lefty = [] #The lane lines are detected by identifying peaks in a histogram of the image #and detecting nonzero pixels in close proximity to the peaks x, y = np.nonzero(np.transpose(combined_binary)) i = 720 j = 630 while j >= 0: histogram = np.sum(combined_binary[j:i, :], axis=0) left_peak = np.argmax(histogram[:640]) x_idx = np.where((((left_peak - 25) < x) & (x < (left_peak + 25)) & ((y > j) & (y < i)))) x_window, y_window = x[x_idx], y[x_idx] if np.sum(x_window) != 0: leftx.extend(x_window.tolist()) lefty.extend(y_window.tolist()) right_peak = np.argmax(histogram[640:]) + 640 x_idx = np.where((((right_peak - 25) < x) & (x < (right_peak + 25)) & ((y > j) & (y < i)))) x_window, y_window = x[x_idx], y[x_idx] if np.sum(x_window) != 0: rightx.extend(x_window.tolist()) righty.extend(y_window.tolist()) i -= 90 j -= 90 lefty = np.array(lefty).astype(np.float32) leftx = np.array(leftx).astype(np.float32) righty = np.array(righty).astype(np.float32) rightx = np.array(rightx).astype(np.float32) left_fit = np.polyfit(lefty, leftx, 2) left_fitx = left_fit[0] * lefty**2 + left_fit[1] * lefty + left_fit[2] right_fit = np.polyfit(righty, rightx, 2) right_fitx = right_fit[0] * righty**2 + right_fit[1] * righty + right_fit[2] rightx_int = right_fit[0] * 720**2 + right_fit[1] * 720 + right_fit[2] rightx = np.append(rightx, rightx_int) righty = np.append(righty, 720) rightx = np.append(rightx, right_fit[0] * 0**2 + right_fit[1] * 0 + right_fit[2]) righty = np.append(righty, 0) leftx_int = left_fit[0] * 720**2 + left_fit[1] * 720 + left_fit[2] leftx = np.append(leftx, leftx_int) lefty = np.append(lefty, 720) leftx = np.append(leftx, left_fit[0] * 0**2 + left_fit[1] * 0 + left_fit[2]) lefty = np.append(lefty, 0) lsort = np.argsort(lefty) rsort = np.argsort(righty) lefty = lefty[lsort] leftx = leftx[lsort] righty = righty[rsort] rightx = rightx[rsort] left_fit = np.polyfit(lefty, leftx, 2) left_fitx = left_fit[0] * lefty**2 + left_fit[1] * lefty + left_fit[2] right_fit = np.polyfit(righty, rightx, 2) right_fitx = right_fit[0] * righty**2 + right_fit[1] * righty + right_fit[2] # Measure Radius of Curvature for each lane line ym_per_pix = 30. / 720 # meters per pixel in y dimension xm_per_pix = 3.7 / 700 # meteres per pixel in x dimension left_fit_cr = np.polyfit(lefty * ym_per_pix, leftx * xm_per_pix, 2) right_fit_cr = np.polyfit(righty * ym_per_pix, rightx * xm_per_pix, 2) left_curverad = ((1 + (2 * left_fit_cr[0] * np.max(lefty) + left_fit_cr[1])**2) **1.5) / np.absolute(2 * left_fit_cr[0]) right_curverad = ( (1 + (2 * right_fit_cr[0] * np.max(lefty) + right_fit_cr[1])**2)** 1.5) / np.absolute(2 * right_fit_cr[0]) # Calculate the position of the vehicle center = abs(640 - ((rightx_int + leftx_int) / 2)) offset = 0 img_size = (img.shape[1], img.shape[0]) src = np.float32([[490, 482], [810, 482], [1250, 720], [40, 720]]) dst = np.float32([[0, 0], [1280, 0], [1250, 720], [40, 720]]) Minv = cv2.getPerspectiveTransform(dst, src) warp_zero = np.zeros_like(combined_binary).astype(np.uint8) color_warp = np.dstack((warp_zero, warp_zero, warp_zero)) pts_left = np.array( [np.flipud(np.transpose(np.vstack([left_fitx, lefty])))]) pts_right = np.array([np.transpose(np.vstack([right_fitx, righty]))]) pts = np.hstack((pts_left, pts_right)) cv2.polylines(color_warp, np.int_([pts]), isClosed=False, color=(0, 0, 255), thickness=40) cv2.fillPoly(color_warp, np.int_([pts]), (0, 255, 0)) newwarp = cv2.warpPerspective( color_warp, Minv, (combined_binary.shape[1], combined_binary.shape[0])) result = cv2.addWeighted(mpimg.imread(image), 1, newwarp, 0.5, 0) f, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 6)) f.tight_layout() ax1.imshow( cv2.cvtColor((warped_image(image, display=False)[0]), cv2.COLOR_BGR2RGB)) ax1.set_xlim(0, 1280) ax1.set_ylim(0, 720) ax1.plot(left_fitx, lefty, color='green', linewidth=3) ax1.plot(right_fitx, righty, color='green', linewidth=3) ax1.set_title('Fit the polynomial function to the lane lines', fontsize=16) ax1.invert_yaxis() # to visualize as we do the images ax2.imshow(result) ax2.set_title('Fill the lane', fontsize=16) if center < 640: ax2.text(200, 100, 'Vehicle is {:.2f}m left of center'.format(center * 3.7 / 700), style='italic', color='white', fontsize=10) else: ax2.text(200, 100, 'Vehicle is {:.2f}m right of center'.format(center * 3.7 / 700), style='italic', color='white', fontsize=10) ax2.text(200, 175, 'Radius of curvature is {}m'.format( int((left_curverad + right_curverad) / 2)), style='italic', color='white', fontsize=10)
def transform(self, img, transform_param): #透视变换 dst = cv2.warpPerspective(img, transform_param, (320, 180)) cv2.imshow('dst', dst) return dst
edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE ) #retrieve the contours as a list, with simple apprximation model contours = sorted(contours, key=cv2.contourArea, reverse=True) #the loop extracts the boundary contours of the page for c in contours: p = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * p, True) if len(approx) == 4: target = approx break approx = mapper.mapp(target) #find endpoints of the sheet pts = np.float32([[0, 0], [800, 0], [800, 800], [0, 800]]) #map to 800*800 target window op = cv2.getPerspectiveTransform(approx, pts) #get the top or bird eye view effect dst = cv2.warpPerspective(orig, op, (800, 800)) cv2.imshow("Scanned", dst)
def process(self, image): return cv2.warpPerspective(image, self.perspectiveTransformMatrix, image.shape[1::-1])
def main(_): global offset, cell_size, template, mx, my train() while True: idx = 12 wx = 0 wy = 0 k = [0] * 9 while idx < 13: img = cv2.imread(path + 'dataset\\' + str(idx) + '.jpg') #lines = open(path+'dataset\\'+str(idx)+'.txt').readlines() edges = compute_edges(img) #show("edges",edges,7) blob = largest_contour(edges) offset = 90 #divisible by 9 points = extract_boundaries(blob) points2 = np.float32([[offset, offset], [val[4] - offset, offset], [offset, val[4] - offset], [val[4] - offset, val[4] - offset]]) m = cv2.getPerspectiveTransform(points, points2) perspective = cv2.warpPerspective(img, m, (val[4], val[4])) edges = compute_edges(perspective) #show("edges",edges,5) cell_size = (val[4] - 2 * offset) // 9 template = cv2.imread(path + 'template.png', 0) w, h = template.shape[1::-1] for i in range(9): for j in range(9): x, y = find_center(edges, i, j) #cv2.circle(perspective,(x,y),10,(255,0,0),10) x -= cell_size // 2 y -= cell_size // 2 digit = np.zeros((cell_size, cell_size)) best_cnt, size, cntrs, h = largest_contour( edges[y + 10:y + cell_size - 9, x + 10:x - 9 + cell_size].copy(), all=True) color_digit = perspective[y:y + cell_size, x:x + cell_size] hsv = cv2.cvtColor(color_digit, cv2.COLOR_BGR2HSV) lower_red = np.array([160, 60, 50]) upper_red = np.array([180, 255, 255]) mask = cv2.inRange(hsv, lower_red, upper_red) res = cv2.bitwise_and(color_digit, color_digit, mask=mask) res = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY) result = 0 if cv2.countNonZero(res) > 140: #cv2.circle(perspective,(x+cell_size//2,y+cell_size//2),10,(0,0,255),10) M = cv2.moments(cntrs[best_cnt]) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) #cv2.circle(perspective,(x+10+cx,y+10+cy),10,(255,0,0),10) digit = cv2.cvtColor( perspective[y + 30 + cy - cell_size // 2:y - 9 + cy + cell_size // 2, x + 30 + cx - cell_size // 2:x - 9 + cx + cell_size // 2], cv2.COLOR_BGR2GRAY) digit = cv2.resize(digit, (28, 28)) _, digit = cv2.threshold( digit, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) #digit = cv2.normalize(digit.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX) #show("digits"+str(i)+','+str(j),digit,1,arrange=True) ''' lbl = int(lines[i][j])-1 k[lbl] += 1 cv2.imwrite(path + "output\\hand\\"+str(lbl+1)+"i"+str(k[lbl])+".jpg",digit) ''' tensor = [] tensor.append(digit.ravel()) tensor = np.array(tensor) ans = int( sess.run(tf.argmax(my, 1), feed_dict={mx: tensor})) elif size > 2000: #cv2.circle(perspective,(x+cell_size//2,y+cell_size//2),70,(0,255,0),8) cv2.drawContours(digit, cntrs, best_cnt, 255, 3, 8, h, 3) x, y, w, h = cv2.boundingRect(cntrs[best_cnt]) digit = cv2.resize(digit[y:y + h, x:x + w], (20, 20)) _, res, _, _ = knn.findNearest( np.array([digit.ravel().astype(np.float32)]), 5) ans = int(res[0]) #show("digits"+str(i)+','+str(j),digit,1,arrange=True) #cv2.imwrite("S:\\Box\\Documents\\code\\Python\\output\\"+lines[i][j]+"\\"+str(idx)+"i_"+str(i)+"_"+str(j)+".jpg",digit) else: ans = '_' print(ans, end='') print() #show("perspective",perspective,5) idx += 1 #if(quit()): break
def warp_image(img,M): img_size = (img.shape[1], img.shape[0]) warped = cv2.warpPerspective(img, M, img_size, flags=cv2.INTER_NEAREST) # keep same size as input image return warped
cos.sort() #get lowest and highest mincos = cos[0] maxcos = cos[-1] #Use the degrees obtained above and the number of vertices #to determine the shape of the contour x, y, w, h = cv2.boundingRect(contours[i]) if (vtc == 4): cv2.putText(frame, 'RECT', (x, y), cv2.FONT_HERSHEY_SIMPLEX, scale, (255, 255, 255), 2, cv2.LINE_AA) cv2.drawContours(frame, [approx], -1, (255, 0, 0), 2) pts_src = np.array(approx, np.float32) h, status = cv2.findHomography(pts_src, pts_dst) warped = cv2.warpPerspective(frame, h, (int(_width + _margin * 2), int(_height + _margin * 2))) cv2.imshow('warped', warped) break #Display the resulting frame #out.write(frame) cv2.imshow('frame', frame) cv2.imshow('canny', canny) if cv2.waitKey(1) == 1048689: #if q is pressed break #When everything done, release the capture cap.release() cv2.destroyAllWindows()
def estimateFeaturePoints(img1o, img2o, debug=False): """ SIFT + Flann knn matching based image registration with homography fitting :param img1o: image 1 ir image to displace (register onto image1) :param img2o: image 2 visible image to be matched (template = reference) :param debug: used to show feature matching :return: aligned image, homography """ img1 = cv2.cvtColor(img1o, cv2.COLOR_BGRA2GRAY) img2 = cv2.cvtColor(img2o, cv2.COLOR_BGRA2GRAY) # Initiate SIFT detector sift = cv2.xfeatures2d.SIFT_create(5000) # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) # FLANN parameters FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) #5 search_params = dict(checks=50) # or pass empty dictionary flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) # Need to draw only good matches, so create a mask matchesMask = [[0, 0] for i in range(len(matches))] # ratio test as per Lowe's paper for i, (m, n) in enumerate(matches): if m.distance < 0.7 * n.distance: #0.7 is nice matchesMask[i] = [1, 0] draw_params = dict(matchColor=(0, 255, 0), singlePointColor=(255, 0, 0), matchesMask=matchesMask, flags=0) if debug: img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params) plt.imshow(img3, ), plt.show() ptsA, ptsB = [], [] # loop over the top matches for (i, (m, n)) in enumerate(matches): if matchesMask[i][0] == 1: ptsA.append(kp1[m.queryIdx].pt) ptsB.append(kp2[m.trainIdx].pt) ptsA = np.array(ptsA, dtype="float") ptsB = np.array(ptsB, dtype="float") # plt.plot(ptsA[:,0], ptsA[:,1], ".r") # plt.plot(ptsB[:,0], ptsB[:,1], ".b") # plt.show() (H, mask) = cv2.findHomography(ptsA, ptsB, method=cv2.RANSAC, ransacReprojThreshold=5.0) (h, w) = img2.shape[:2] aligned = None if not debug else cv2.warpPerspective(img1o, H, (w, h)) return aligned, H
def draw(orign, predict_img, left_fit, right_fit): M, Minv = perspective() warped = warp(np.uint8(predict_img * 255)) cv2.imwrite('./newwarp.jpg', warped) warp_zero = np.zeros_like(warped).astype(np.uint8) color_warp = np.dstack((warp_zero, warp_zero, warp_zero)) plot_y = np.linspace(0, warped.shape[0] - 1, warped.shape[0]) left_fit_x = left_fit[0] * plot_y**2 + left_fit[1] * plot_y + left_fit[2] right_fit_x = right_fit[0] * plot_y**2 + right_fit[1] * plot_y + right_fit[ 2] middle_fit_x = (left_fit_x + right_fit_x) / 2 dy = 2 * left_fit[0] * 710 + left_fit[1] ddy = 2 * left_fit[0] R = ((1 + dy**2)**(3 / 2)) / ddy * 2.87 / 584 pts_left = np.array([np.transpose(np.vstack([left_fit_x, plot_y]))]) pts_right = np.array( [np.flipud(np.transpose(np.vstack([right_fit_x, plot_y])))]) pts_middle = np.array( [np.flipud(np.transpose(np.vstack([middle_fit_x, plot_y])))]) PTS = np.hstack(pts_middle) pts = np.hstack((pts_left, pts_right)) try: cv2.fillPoly( color_warp, np.int_([pts]), (0, 255, 0), ) cv2.polylines(color_warp, np.int_([PTS]), isClosed=False, color=(0, 0, 255), thickness=5) cv2.polylines(color_warp, np.int_([pts]), isClosed=False, color=(255, 150, 0), thickness=8) except: pass cv2.imwrite('./newwarp0.jpg', color_warp) newwarp = cv2.warpPerspective(color_warp, Minv, (880, 246)) cv2.imwrite('./newwarp1.jpg', newwarp) newwarp = cv2.copyMakeBorder(newwarp, 420, 54, 200, 200, cv2.BORDER_CONSTANT, value=[0, 0, 0]) result = cv2.addWeighted(orign, 1, newwarp, 0.3, 0) cv2.imwrite('./result.jpg', result) try: cv2.putText(result, str('Radius of curvature:') + str(round(R, 2)), (60, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 5), 1) print(str('Radius of curvature:') + str(round(R, 2)) + 'm') except: pass #offset center left_point = left_fit[0] * 700**2 + left_fit[1] * 700 + left_fit[2] right_point = right_fit[0] * 700**2 + right_fit[1] * 700 + right_fit[2] lane_center = (left_point + right_point) / 2 off_center = (result.shape[1] / 2 - lane_center) * (3 / 734) off_center = round(off_center, 3) if off_center < 0: print("Offset to right:", abs(off_center), str("m")) center_messages = "Offset to right: : " + str( abs(off_center)) + str("m") if off_center > 0: print("Offset to left:", abs(off_center), str("m")) center_messages = "Offset to left:" + str(abs(off_center)) + str("m") if off_center == 0: print("On the center:", abs(off_center), str("m")) cv2.putText(result, center_messages, (60, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1) return result
def warp_image(self, image): warped_image = cv2.warpPerspective(image, self.homo_matrix, dsize=self.whole_size) return warped_image
def processing(img, object_points, img_points, M, Minv, left_line, right_line): # camera calibration, image distortion correction # undist = utils.cal_undistort(img,object_points,img_points) cv2.imshow("img", img) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 设置阈值下限和上限,去除背景颜色 lower_red = np.array([80, 0, 0]) upper_red = np.array([160, 255, 150]) lower_white = np.array([0, 0, 221]) upper_white = np.array([180, 30, 255]) lower_yellow = np.array([100, 43, 46]) upper_yellow = np.array([120, 255, 255]) lower_lane = np.array([0, 0, 50]) upper_lane = np.array([180, 43, 120]) # 创建掩膜 # 将原图像和掩膜做位与运算 white_img = colorMask("white_mask", img, hsv, lower_white, upper_white) # yellow_img = colorMask("yellow_mask", img, hsv, lower_yellow, upper_yellow) # lane_img = colorMask("lane_mask", img, hsv, lower_lane, upper_lane) undist = img gray = cv2.cvtColor(white_img, cv2.COLOR_RGB2GRAY) ret, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE) ret, binary2 = cv2.threshold(gray, 200, 1, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE) #cv2.imshow("binary", binary) rgb = cv2.cvtColor(binary, cv2.COLOR_GRAY2RGB) cv2.imshow("rgb", rgb) #cv2.imshow("binary2", binary) # get the thresholded binary image thresholded = thresholding(rgb) cv2.imshow("thresholded*255", thresholded * 255) #perform perspective transform thresholded_wraped = cv2.warpPerspective(binary2, M, img.shape[1::-1], flags=cv2.INTER_LINEAR) cv2.imshow("thresholded_wraped*255", thresholded_wraped * 255) #perform detection if left_line.detected and right_line.detected: print("find line") left_fit, right_fit, left_lane_inds, right_lane_inds = utils.find_line_by_previous( thresholded_wraped, left_line.current_fit, right_line.current_fit) else: print("no find line") left_fit, right_fit, left_lane_inds, right_lane_inds = utils.find_line( thresholded_wraped) left_line.update(left_fit) right_line.update(right_fit) #draw the detected laneline and the information area_img = utils.draw_area(undist, thresholded_wraped, Minv, left_fit, right_fit) cv2.imshow("area_img", area_img) cv2.waitKey(50) #print(area_img) #curvature,pos_from_center = utils.calculate_curv_and_pos(thresholded_wraped,left_fit, right_fit) #result = utils.draw_values(area_img,curvature,pos_from_center) #result=area_img result = rgb return result
print(dst_points) # draw the trapezoid cv2.polylines(img, [src_points.astype(np.int32)], True, (0, 0, 255), thickness=5) #find the projection matrix M = cv2.getPerspectiveTransform(src_points, dst_points) min_wid = 1000 for img_path in straight_images: img = pimg.imread(img_path) img = cv2.undistort(img, cam_matrix, dist_coeffs) img = cv2.warpPerspective(img, M, settings.UNWARPED_SIZE) img_hsl = cv2.cvtColor(img, cv2.COLOR_RGB2HLS) mask = img_hsl[:, :, 1] > 128 mask[:, :50] = 0 mask[:, -50:] = 0 mom = cv2.moments(mask[:, :settings.UNWARPED_SIZE[0] // 2].astype( np.uint8)) x1 = mom["m10"] / mom["m00"] mom = cv2.moments(mask[:, settings.UNWARPED_SIZE[0] // 2:].astype(np.uint8)) x2 = settings.UNWARPED_SIZE[0] // 2 + mom["m10"] / mom["m00"] cv2.line(img, (int(x1), 0), (int(x1), settings.UNWARPED_SIZE[1]), (255, 0, 0), 3) cv2.line(img, (int(x2), 0), (int(x2), settings.UNWARPED_SIZE[1]), (0, 0, 255), 3) if (x2 - x1 < min_wid):
def execute(change): global robot, frames print("\rFrames", frames, end="") frames += 1 img = cv2.resize(change["new"], (640, 360)) #row col h, w = img.shape[:2] # undistort #dst = cv2.undistort(img, mtx, dist, None, newcameramtx) # Detect Red line hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hsv_red2 = np.array([180, 255, 255]) hsv_red1 = np.array([0, 125, 70]) red = cv2.inRange(hsv, hsv_red1, hsv_red2) # Find target point j = 0 k = 0 for i in range(640): if red[270, i] > 0: j = j + i k = k + 1 if k != 0: center = j / k else: center = 0 # Transform to IPM # - red line center ipm_ = np.dot(proj_mat, np.array([center, 270, 1])) ipm_ = ipm_ / ipm_[2] # - crnter of image ipm_ref = np.dot(proj_mat, np.array([320, 270, 1])) ipm_ref = ipm_ref / ipm_ref[2] # -the bottom of image ipm_cam = np.dot(proj_mat, np.array([640, 270, 1])) ipm_cam = ipm_cam / ipm_cam[2] # Visualize _map = cv2.bitwise_and(img, img, mask=red) cv2.circle(_map, (int(center), 270), 6, (255, 255, 0)) cv2.circle(_map, (320, 270), 6, (255, 0, 0)) warped = cv2.warpPerspective(img, proj_mat, (w, h)) cv2.circle(warped, (int(ipm_[0]), int(ipm_[1])), 6, (255, 255, 0)) cv2.circle(warped, (int(ipm_ref[0]), int(ipm_ref[1])), 6, (255, 0, 0)) cv2.putText(warped, str((int(ipm_[0]), int(ipm_[1]))), (180, 250), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2, cv2.LINE_AA) cv2.putText(warped, str((int(ipm_ref[0]), int(ipm_ref[1]))), (320, 250), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2, cv2.LINE_AA) cv2.putText(warped, str((int(ipm_cam[0]), int(ipm_cam[1]))), (320, 330), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2, cv2.LINE_AA) cv2.imshow("warped", warped) cv2.imshow("camera", _map) ## Pure Pursuit Control next_w = controller.feedback(((ipm_ref[0] - ipm_[0]) * 0.001, 0.191), v) if center != 0: value_l = v + car_width * next_w / 2 value_r = v - car_width * next_w / 2 else: value_l = 0 value_r = 0 robot.set_motor(value_l, value_r) ## Camera acce img = cv2.resize(change["new"], (640, 360)) cv2.imshow("camera", img) ret, objp, corners = detect_chessboard(img) if ret != 0: R, T = solve_dis(objp, corners, Matrix, k) print(R) print(T) print(math.sqrt(T[0]**2 + T[1]**2 + T[2]**2))
import cv2 import numpy as np img = cv2.imread('example.jpg') width = 430 height = 595 p1 = np.float32([[1072, 256], [1480, 191], [1092, 850], [1519, 852]]) p2 = np.float32([[0, 0], [width, 0], [0, height], [width, height]]) matrix = cv2.getPerspectiveTransform(p1, p2) imgcropped = cv2.warpPerspective(img, matrix, (width, height)) cv2.imshow("OriginalImage", img) cv2.imshow("CroppedImage", imgcropped) cv2.waitkey(0)
def process_video_from_file(self, video_file): '''Main function for processing data input from a video file''' cap = cv2.VideoCapture(video_file) while cap.isOpened(): # read video frame ret, frame = cap.read() frame_copy = frame self.color_calibration = int(np.mean(frame)) # image processing frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(frame_gray, (5, 5), 0) dst = cv2.undistort(blur, self.K, self.dist) # canny = cv2.Canny(frame,50,100) sobel_x = cv2.Sobel(dst, cv2.CV_64F, 1, 0, ksize=3) sobel_y = cv2.Sobel(dst, cv2.CV_64F, 0, 1, ksize=3) abs_sobel_x = np.absolute(sobel_x) sobel_x = np.uint8(abs_sobel_x) abs_sobel_y = np.absolute(sobel_y) sobel_y = np.uint8(abs_sobel_y) grad = cv2.addWeighted(sobel_x, 0.75, sobel_y, 0.25, 0) # crop out sky sky_box = np.array([[[0, 0], [1280, 0], [1280, 470], [0, 470]]], 'int32') left_box = np.array([[[0, 0], [350, 0], [350, 960], [0, 960]]], 'int32') right_box = np.array( [[[1000, 0], [1280, 0], [1280, 960], [1000, 960]]], 'int32') cv2.fillPoly(dst, sky_box, black) cv2.fillPoly(dst, left_box, black) cv2.fillPoly(dst, right_box, black) # find lane line colors wy_rgb, wy_hls, wy_hsv, combine, c_white, c_yellow = self.get_colored_lines( frame) cv2.fillPoly(wy_rgb, sky_box, black) cv2.fillPoly(wy_hls, sky_box, black) cv2.fillPoly(wy_hsv, sky_box, black) cv2.fillPoly(combine, sky_box, black) cv2.fillPoly(combine, left_box, black) cv2.fillPoly(combine, right_box, black) # unwarp frame unwarp = cv2.warpPerspective(combine, self.H, (960, 1050)) unwarp_yellow = cv2.warpPerspective(c_yellow, self.H, (960, 1050)) unwarp_white = cv2.warpPerspective(c_white, self.H, (960, 1050)) unwarp_orig = cv2.warpPerspective(frame, self.H, (960, 1050)) unwarp_yellow_gray = cv2.cvtColor(unwarp_yellow, cv2.COLOR_BGR2GRAY) y_hist, y_graph = self.histogram(unwarp_yellow_gray) unwarp_white_gray = cv2.cvtColor(unwarp_white, cv2.COLOR_BGR2GRAY) w_hist, w_graph = self.histogram(unwarp_white_gray) # remove white block at bottom of histogram graph y_graph = y_graph[:-90, :] w_graph = w_graph[:-90, :] # process histogram data y_dist = self.process_histogram(y_graph, offset=20) w_dist = self.process_histogram(w_graph, offset=20) # convert grayscale graph to rgb (to match array dimensions) # graph = cv2.cvtColor(graph,cv2.COLOR_GRAY2RGB) y_graph = cv2.cvtColor(y_graph, cv2.COLOR_GRAY2RGB) w_graph = cv2.cvtColor(w_graph, cv2.COLOR_GRAY2RGB) # lane_bounds = self.get_lane_bounds(dist,graph,offset=20,show_lines=True) y_lane_bounds = self.get_lane_bounds(y_dist, y_graph, offset=20, show_lines=False) w_lane_bounds = self.get_lane_bounds(w_dist, w_graph, offset=20, show_lines=False) w_peaks = self.filter_histogram(w_hist, w_graph, w_lane_bounds, show=False) w_max_peak = self.filter_peaks(w_peaks, w_graph) # self.draw_ROIs(lane_bounds,graph) # lane_polys, radii = self.fit_lane_lines(lane_bounds,unwarp,0,show_lines=) y_lane_polys, y_radii = self.fit_lane_lines(y_lane_bounds, unwarp, 0, show_lines=True) w_lane_polys, w_radii = self.fit_lane_lines(w_lane_bounds, unwarp, w_max_peak, show_lines=True, use_peak=True) lane_polys = y_lane_polys + w_lane_polys self.color_lanes(lane_polys, unwarp_orig, unwarp, show_main=True, show_secondary=False) final = cv2.warpPerspective(unwarp_orig, np.linalg.inv(self.H), (frame.shape[1], frame.shape[0])) final = cv2.addWeighted(final, 0.25, frame, 1.0, 0) # combine the unwarped colored lines frame with the histogram graph graph = cv2.bitwise_or(y_graph, w_graph) graph_display = np.vstack((unwarp, graph[400:, :])) # show radius and lane data font = cv2.FONT_HERSHEY_SIMPLEX # print(radii,px_to_m) try: radius = int(round(y_radii[0] / px_to_m)) except: radius = 0 # print('NOT ENOUGH LINES FOUND') direction = np.sign(radius) # print(direction,direction<0,radius) offset = round((3.7 / 2) - self.calculate_offset(y_lane_bounds, graph_display), 4) cv2.putText( final, 'Radius: ' + (str(abs(radius)) + 'm' if abs(radius) <= 20000 else 'Straight'), (25, 50), font, 1, (0, 0, 255), 2, cv2.LINE_AA) cv2.putText(final, 'Vehicle is ' + str(offset) + 'm left of center', (25, 90), font, 1, (0, 0, 255), 2, cv2.LINE_AA) cv2.putText( final, 'Vehicle is ' + ('moving straight' if abs(radius) > 20000 else ('turning left' if direction < 0 else 'turning right')), (25, 130), font, 1, (0, 0, 255), 2, cv2.LINE_AA) # display figures # cv2.imshow('orig',cv2.resize(frame,(0,0),fx=0.5,fy=0.5)) cv2.imshow('final', cv2.resize(final, (0, 0), fx=0.5, fy=0.5)) # cv2.imshow('lane hist',cv2.resize(graph_display,(0,0),fx=0.5,fy=0.5)) cv2.imwrite('frame_grab.png', frame) if cv2.waitKey(1) & 0xFF == ord('q'): self.running = False break cap.release() cv2.destroyAllWindows()
def get_single_image_mesh_plane( plane_params, segmentations, img_file, height=480, width=640, focal_length=517.97, webvis=False, tolerance=0, ): plane_params = np.array(plane_params) offsets = np.linalg.norm(plane_params, ord=2, axis=1) norms = plane_params / offsets.reshape(-1, 1) if type(segmentations[0]) == dict: poly_segmentations = rle2polygon(segmentations, tolerance) else: poly_segmentations = segmentations verts_list = [] faces_list = [] verts_uvs = [] uv_maps = [] imgs = [] for segm, normal, offset in zip(poly_segmentations, norms, offsets): if len(segm) == 0: continue I = np.array(imageio.imread(img_file)) HUse = None # save uv_map tmp_verts = [] for s in segm: tmp_verts.extend(s) tmp_verts = np.array(tmp_verts).reshape(-1, 2) # pick an arbitrary point # get 3d pointcloud tmp_pcd = get_pcd(tmp_verts, normal, offset, focal_length) point0 = tmp_pcd[0, :] # pick the furthest point from here dPoint0 = np.sum((tmp_pcd - point0[np.newaxis, :]) ** 2, axis=1) point1 = tmp_pcd[np.argmax(dPoint0), :] # dir1 and dir2 are orthogonal to the normal dir1 = point1 - point0 dir1 = dir1 / np.linalg.norm(dir1) dir2 = np.cross(dir1, normal) # control points in 3D control3D = [point0, point0 + dir1, point0 + dir2, point0 + dir1 + dir2] control3D = np.vstack([p[None, :] for p in control3D]) control3DProject = project2D(control3D, focal_length) # pick an arbitrary square targetSize = 300 fakePoints = np.array( [[0, 0], [0, targetSize], [targetSize, 0], [targetSize, targetSize]] ).astype(np.float32) # fit, then adjust H = cv2.getPerspectiveTransform(control3DProject.astype(np.float32), fakePoints) # this maps the control points to the square; now make sure the full mask warps in P = cv2.perspectiveTransform(tmp_verts.reshape(1, -1, 2), H)[0, :, :] xTrans, yTrans = P[:, 0].min(), P[:, 1].min() maxScale = max(P[:, 0].max() - P[:, 0].min(), P[:, 1].max() - P[:, 1].min()) HShuffle = np.array( [ [targetSize / maxScale, 0, -xTrans * targetSize / maxScale], [0, targetSize / maxScale, -yTrans * targetSize / maxScale], [0, 0, 1], ] ) HUse = HShuffle @ H # warped_image is now the rectified image; warped_image2 has it with a 100px fudge factor warped_image = cv2.warpPerspective(I, HUse, (targetSize, targetSize)) uv_maps.append(warped_image) verts_3d = [] faces = [] uvs = [] for ring in segm: verts = np.array(ring).reshape(-1, 2) # get 3d pointcloud pcd = get_pcd(verts, normal, offset, focal_length) if webvis: # Rotate by 11 degree around x axis to push things on the ground. pcd = ( np.array([[-1, 0, 0], [0, 1, 0], [0, 0, -1]]) @ np.array( [ [1, 0, 0], [0, 0.9816272, -0.1908090], [0, 0.1908090, 0.9816272], ] ) @ np.array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]]) @ pcd.T ).T uvsRectified = cv2.perspectiveTransform( verts.astype(np.float32).reshape(1, -1, 2), HUse )[0, :, :] uvsRectified = np.array([0, 1]) + np.array( [1, -1] ) * uvsRectified / np.array([targetSize, targetSize]) uvs.extend(uvsRectified) # triangulate polygon using earcut algorithm triangles = earcut.triangulate_float32(verts, [len(verts)]) # add base index of vertice triangles += len(verts_3d) triangles = triangles.reshape(-1, 3) # convert to counter-clockwise triangles[:, [0, 2]] = triangles[:, [2, 0]] if triangles.shape[0] == 0: continue verts_3d.extend(pcd) faces.extend(triangles) verts_list.append(torch.tensor(verts_3d, dtype=torch.float32)) faces_list.append(torch.tensor(faces, dtype=torch.int32)) verts_uvs.append(torch.tensor(uvs, dtype=torch.float32)) imgs.append(torch.FloatTensor(imageio.imread(img_file))) # pytorch3d mesh verts_uvs = pad_sequence(verts_uvs, batch_first=True) faces_uvs = pad_sequence(faces_list, batch_first=True, padding_value=-1) tex = Textures(verts_uvs=verts_uvs, faces_uvs=faces_uvs, maps=imgs) meshes = Meshes(verts=verts_list, faces=faces_list, textures=tex) return meshes, uv_maps
def unWrap(self, image): return cv2.warpPerspective(image, self.revPerspectiveTransformationMatrix, image.shape[1::-1])
def get_persp(image, pts): ippts = np.float32(pts) Map = cv2.getPerspectiveTransform(ippts, oppts) warped = cv2.warpPerspective(image, Map, (AR[1], AR[0])) return warped
def The_Main(counte): ar = 0 count = 0 video = cv2.VideoCapture(0, cv2.CAP_DSHOW) video.set(3, 1280) video.set(4, 720) while True: # capture frame by frame ret, frame = video.read() k = 0 # our functions on the frame come here # preprocessing image gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # gray scale gaussian_blur = cv2.GaussianBlur(gray, (5, 5), 3) # removes noise from image adaptive_threshold = cv2.adaptiveThreshold( gaussian_blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # threshold set out for background and foreground pixels # getting the largest square # contours is numpy array of all continous point obtained in picture(contour)...the boundaries of a shape with the same intensity. # RETR_LIST ---> it creates the hieracrchy of all the contours in image,i.e who is outerone,innerone etc contours, hierarchy = cv2.findContours(adaptive_threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # max is variable for maximum area and maxc for maximum contours maxc = [0] max = 0 # loop to find the largest contour in given frame for i in range(len(contours)): # finding the perimeter of contour and contour approximation perimeter = cv2.arcLength( contours[i], True ) # true if curve is closed...perimeter means length of arc epsilon = 0.03 * perimeter approx = cv2.approxPolyDP(contours[i], epsilon, True) if cv2.contourArea(contours[i]) > 100000 and cv2.contourArea( contours[i]) > max and len(approx) == 4: # checking maximum contours max = cv2.contourArea(contours[i]) maxc = approx # if contour have four corners then saving that frame and drawing contours if len(maxc) == 4: count = count + 1 else: count = 0 if len(maxc) == 4: cv2.drawContours(frame, [maxc], -1, (255, 0, 2), 3) cv2.drawContours(frame, maxc, -1, (0, 255), 8) # displaying contour edges and corner cv2.imshow('all', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break if count == 4: cv2.imwrite("frame.jpg", frame) k = 1 if k == 1: ar = maxc.copy() # check_for_square(ar) # checking if maxc is approx square (x, y) = adaptive_threshold.shape mask = np.zeros((x, y, 3), np.uint8) mask = cv2.drawContours(mask, [ar], -1, (255, 255, 255), -1) mask = cv2.drawContours(mask, ar, -1, (0, 255), 2) kernel = cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (11, 11)) # kernel for ellipitcal shape close = cv2.morphologyEx( frame, cv2.MORPH_CLOSE, kernel) # closes the pores in foreground div = np.float32( frame ) / close # the closed and gray images are divided to get a narrow histogram which when normalized increases the brightness and contrast of image res = np.uint8(cv2.normalize(div, div, 0, 255, cv2.NORM_MINMAX)) masked = cv2.bitwise_and(mask, res) masked = cv2.cvtColor(masked, cv2.COLOR_BGR2GRAY) ar = rearrange_clockwise(ar) dest = np.array(ar, np.float32) # source nw = np.array([[0, 0], [0, 450], [450, 450], [450, 0]], np.float32) # destinaton M = cv2.getPerspectiveTransform(dest, nw) output = cv2.warpPerspective(res, M, (450, 450)) output = cv2.GaussianBlur(output, (3, 3), 0) # output = cv2.adaptiveThreshold(output,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2) output = cv2.rectangle(output, (0, 0), (450, 450), 0, 1) cv2.imshow("output", output) # extracting digits from grid size = 9 grid = [] for i in range(size): row = [] for j in range(size): row.append(0) grid.append(row) height = output.shape[0] // 9 width = output.shape[1] // 9 offset_width = math.floor( width / 10) # offset is used to get rid of boundaries offset_height = math.floor(height / 10) # divide the sudoku board into 9*9 square boxes # square containing numbers will be stored in crop_image max = 0 max2 = 0 for i in range(size): for j in range(size): # crop image with offset # offset : VISIBLE content & padding + border + scrollbar #cropping the image by image matrix image[height,width] crop_image = output[height * i + offset_height:height * (i + 1) - offset_height, width * j + offset_width:width * (j + 1) - offset_width] # cropping images more crop_image = crop_image[2:38, 2:38] #cv2.imshow("crop_image", crop_image) #cv2.waitKey(0) crop_image = cv2.cvtColor(crop_image, cv2.COLOR_BGR2GRAY) crop_image = cv2.GaussianBlur(crop_image, (3, 3), 0) _, crop_image = cv2.threshold(crop_image, 210, 255, cv2.THRESH_BINARY) # has too little black pixels # digit_pic_size**2 -> area of image of digit.It is in square digit_pic_size = 28 crop_image = cv2.resize( crop_image, (digit_pic_size, digit_pic_size)) if crop_image.sum() >= digit_pic_size**2 * 255 - 255: #print("digit size") grid[i][j] = 0 continue # move on if we have a white cell #print("out") # criteria 2 for detecting white cell # huge white area in centre centre_width = crop_image.shape[1] // 2 # column centre_height = crop_image.shape[0] // 2 # row x_start = centre_height // 2 x_end = centre_height // 2 + centre_height y_start = centre_width // 2 y_end = centre_width // 2 + centre_width centre_region = crop_image[x_start:x_end, y_start:y_end] if centre_region.sum( ) >= centre_width * centre_height * 255 - 255: print("in in secong if") grid[i][j] = 0 continue # move on if we have white cell print("out from 2 if") # now we dont have any white cell #cv2.imshow("crop_image", crop_image) #cv2.waitKey(0) # centralize the image according to centre of mass crop_image = cv2.bitwise_not(crop_image) shift_x, shift_y = get_best_shift(crop_image) shifted = shift(crop_image, shift_x, shift_y) crop_image = shifted crop_image = cv2.bitwise_not(crop_image) #cv2.imshow("crop_image", crop_image) #cv2.imwrite("crop()_image{0}.png".format(i), crop_image) #cv2.waitKey(0) _, crop_thresh = cv2.threshold( crop_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) #cv2.imshow("crop_image", crop_thresh) #cv2.imwrite("crop()_image{0}.png".format(i), crop_image) #cv2.waitKey(0) # recognizing digits prediction = model.predict( [crop_thresh.reshape(1, 28, 28, 1)]) grid[i][j] = np.argmax(prediction[0]) + 1 user_grid = copy.deepcopy(grid) #print("grid", grid) #print("user_grid", user_grid) ################################################# #Solving the sudoku sudoku_solved = sudoku_solution.search( sudoku_solution.parse_grid(grid)) print(sudoku_solved) if (sudoku_solved == False): print("NOISE ATTAINED>>>>>RESTART") try: The_Main(counter + 1) except: if counter == 5: print("This cannnot be solved") exit() else: sudoku_solved = list(sudoku_solved.values()) sudoku_solved = np.asarray(sudoku_solved).reshape(9, 9) original_warp = write_solution_on_image( output, sudoku_solved, user_grid) # cv2.imshow("write sol on image", original_warp) # cv2.waitKey(0) old_sudoku = copy.deepcopy(grid) dest = np.array(ar, np.float32) nw = np.array([[0, 0], [0, 450], [450, 450], [450, 0]], np.float32) M = cv2.getPerspectiveTransform(dest, nw) #apply inverse perspective transform and paste the solutions on top of the original image result_sudoku = cv2.warpPerspective( original_warp, M, (frame.shape[1], frame.shape[0]), flags=cv2.WARP_INVERSE_MAP) print(np.asarray(result_sudoku).shape) result = np.where( result_sudoku.sum(axis=-1, keepdims=True) != 0, result_sudoku, frame) print("reached here") cv2.imshow("final image", result) cv2.waitKey(0) video.release() cv2.destroyAllWindows()