def removeBackground(self, image): discValue = 10 threshold = 1 hsvt = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) for roiHist in self.negHistograms: dst = cv2.calcBackProject([hsvt],[0,1],roiHist,[0,180,0,256],1) cv2.imshow('dst', dst) disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(discValue,discValue)) cv2.filter2D(dst, -1,disc,dst) ret,thresh = cv2.threshold(dst,threshold,255,cv2.THRESH_BINARY_INV) thresh = cv2.merge((thresh,thresh,thresh)) image = cv2.bitwise_and(image,thresh) for roiHist in self.posHistograms: dst = cv2.calcBackProject([hsvt],[0,1],roiHist,[0,180,0,256],1) #cv2.imshow('dst', dst) disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(discValue,discValue)) cv2.filter2D(dst, -1,disc,dst) ret,thresh = cv2.threshold(dst,threshold,255,cv2.THRESH_BINARY) thresh = cv2.merge((thresh,thresh,thresh)) image = cv2.bitwise_and(image,thresh) #res = np.hstack((thresh,res)) cv2.imshow('backProj', image) return image
def GetGlints(gray,thr): tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR) #used to draw temporary results props = RegionProps() val,binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY) #Using non inverted binary image #Combining opening and dialiting seems to be the best but is it ok that other glints are visible two?????!!!!! st7 = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7)) st9 = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7)) binI= cv2.morphologyEx(binI, cv2.MORPH_OPEN, st7) binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st9, iterations=2) cv2.imshow("ThresholdGlints",binI) #Calculate blobs sliderVals = getSliderVals() #Getting slider values contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) #Finding contours/candidates for pupil blob glints = [] glintEllipses = [] for cnt in contours: values = props.CalcContourProperties(cnt,['Area','Length','Centroid','Extend','ConvexHull']) #BUG - Add cnt.astype('int') in Windows if values['Area'] < sliderVals['maxSizeGlints'] and values['Area'] > sliderVals['minSizeGlints']: glints.append(values) centroid = (int(values['Centroid'][0]),int(values['Centroid'][1])) cv2.circle(tempResultImg,centroid, 2, (0,0,255),4) glintEllipses.append(cv2.fitEllipse(cnt)) cv2.imshow("TempResults",tempResultImg) return glintEllipses
def applyMorphologicalCleaning(self, image): """ Applies a variety of morphological operations to improve the detection of worms in the image. Takes 0.030 s on MUSSORGSKY for a typical frame region Takes 0.030 s in MATLAB too """ # start with worm == 1 image = image.copy() segmentation.clear_border(image) # remove objects at edge (worm == 1) # fix defects in the thresholding by closing with a worm-width disk # worm == 1 wormSE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (self.wormDiskRadius+1, self.wormDiskRadius+1)) imcl = cv2.morphologyEx(np.uint8(image), cv2.MORPH_CLOSE, wormSE) imcl = np.equal(imcl, 1) # fix defects by filling holes imholes = ndimage.binary_fill_holes(imcl) imcl = np.logical_or(imholes, imcl) # fix barely touching regions # majority with worm pixels == 1 (median filter same?) imcl = nf.median_filter(imcl, footprint=[[1, 1, 1], [1, 0, 1], [1, 1, 1]]) # diag with worm pixels == 0 imcl = np.logical_not(bwdiagfill(np.logical_not(imcl))) # open with worm pixels == 1 openSE = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1)) imcl = cv2.morphologyEx(np.uint8(imcl), cv2.MORPH_OPEN, openSE) return np.equal(imcl, 1)
def find_yellow_contours(self, split_image): lab_bthreshed_board = cv2.adaptiveThreshold(split_image.lab[2], 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, self.options["board_blocksize"], self.options["board_C_b"]) yuv_uthreshed_board = cv2.adaptiveThreshold(split_image.yuv[2], 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, self.options["board_blocksize"], self.options["board_C_u"]) yuv_uthreshed_board = cv2.bitwise_not(yuv_uthreshed_board) finalThreshed = lab_bthreshed_board & yuv_uthreshed_board # Erode and dilate thresholded images morph_size = self.options["board_morph_size"] erode_element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (morph_size * 2 + 1, morph_size * 2 + 1), (morph_size, morph_size)) dilate_element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (morph_size * 2 + 1, morph_size * 2 + 1), (morph_size, morph_size)) eroded = cv2.erode(finalThreshed,erode_element, iterations = self.options["board_morph_iter"]) finalThreshed = cv2.dilate(eroded, dilate_element, iterations = self.options["board_morph_iter"]) finalThreshed = cv2.dilate(finalThreshed, dilate_element, iterations = self.options["board_morph_iter"]) finalThreshed = cv2.erode(finalThreshed, erode_element, iterations = self.options["board_morph_iter"]) self.post_if_enabled('yellow_lab_bthreshed', lab_bthreshed_board) self.post_if_enabled('yellow_yuv_uthreshed', yuv_uthreshed_board) self.post_if_enabled('yellow_binary_image', finalThreshed) _, contours, hierarchy = cv2.findContours(np.copy(finalThreshed), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) return contours, hierarchy
def GetPupil(gray,thr): tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR) #used to draw temporary results props = RegionProps() val,binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY_INV) #Combining Closing and Opening to the thresholded image st7 = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7)) st9 = cv2.getStructuringElement(cv2.MORPH_CROSS,(9,9)) st15 = cv2.getStructuringElement(cv2.MORPH_CROSS,(15,15)) binI = cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st9) #Close binI= cv2.morphologyEx(binI, cv2.MORPH_OPEN, st15) #Open binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st7, iterations=2) #Dialite cv2.imshow("ThresholdPupil",binI) #Calculate blobs sliderVals = getSliderVals() #Getting slider values contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) #Finding contours/candidates for pupil blob pupils = [] pupilEllipses = [] for cnt in contours: values = props.CalcContourProperties(cnt,['Area','Length','Centroid','Extend','ConvexHull']) #BUG - Add cnt.astype('int') in Windows if values['Area'] < sliderVals['maxSizePupil'] and values['Area'] > sliderVals['minSizePupil'] and values['Extend'] < 0.9: pupils.append(values) centroid = (int(values['Centroid'][0]),int(values['Centroid'][1])) cv2.circle(tempResultImg,centroid, 2, (0,0,255),4) pupilEllipses.append(cv2.fitEllipse(cnt)) cv2.imshow("TempResults",tempResultImg) return pupilEllipses
def cleanup_mask(mask, erode_val, dilate_val): kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (erode_val,erode_val)) mask = cv2.erode(mask, kernel) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (dilate_val,dilate_val)) mask = cv2.dilate(mask, kernel) return mask
def processImage(pos): if(pos<1): return imgOriginal=cv2.imread('coins.png',0) retval, img=cv2.threshold(imgOriginal, 0, 255, cv2.THRESH_OTSU) #Close the entire image using a kernel defined by the user. kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (pos,pos)) closedImage=cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) #Use a second kernel to remove the small coins from the image by subtracting #closed image minus the large coins only image kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (pos+40,pos+40)) largeCoinsImg = cv2.morphologyEx(closedImage, cv2.MORPH_OPEN, kernel) smallCoinsImg = closedImage - largeCoinsImg #Performing the erosion processing smallCoinsImg = cv2.morphologyEx(smallCoinsImg, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (19, 19))) kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (35,35)) smallCoinsImg = cv2.erode(smallCoinsImg, kernel) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (35,35)) smallCoinsImg = cv2.dilate(smallCoinsImg, kernel) finalRes = colorImage(imgOriginal, smallCoinsImg, largeCoinsImg) #Show the trackbar and the image cv2.imshow("Final Result", finalRes) cv2.imwrite("Final Image.jpg", finalRes)
def fillHoles(self): #create erode and dilate kernels erodeKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) dilateKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(15,15)) #Perform Erode and dilate to fill holes in image self.frame = cv2.erode(self.frame,erodeKernel) self.frame = cv2.dilate(self.frame, dilateKernel)
def backproject(): im = cv2.imread("DSC_0869.JPG") #im = cv2.resize(im, None, fx = 0.25, fy = 0.25) #image => hsv, hist hsv = cv2.cvtColor( im, cv2.COLOR_BGR2HSV) #cv2.imshow("hsv", hsv) imHist = cv2.calcHist([hsv], [0,1], None, [180, 256],[0,180,0,256]) bckP = cv2.calcBackProject([hsv], [0,1], imHist,[0,180,0,256], 1) #cv2.imshow("bp", bckP) kernel = cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (3,3)) closing = cv2.morphologyEx(bckP, cv2.MORPH_CLOSE, kernel) #cv2.imshow("eroded", closing) ##dst = cv2.filter2D(closing, -1,kernel) ##cv2.imshow('2d', dst) ret,thresh = cv2.threshold(closing, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) #cv2.imshow("thresh", thresh) fm1 = cv2.merge((thresh,thresh,thresh)) res1 = cv2.bitwise_and(im, fm1, mask = None)# mask here has no significance #cv2.imshow("first and", res1) #make (lower bound) G= 180 for proper target. G= 90 makes its edges disappear a leeettle mask = cv2.inRange(hsv, np.array([5,90,50], dtype = np.uint8), np.array([49,255,205], dtype = np.uint8)) mask_inv = cv2.bitwise_not(mask) res = cv2.bitwise_and(res1, res1, mask = mask_inv) cv2.imwrite("final.jpg", res) kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) res=cv2.erode(res,kernel,iterations=1) cv2.imwrite("bckP.JPG",res) extractblob(res)
def get_binary_from_hsv(card): # convert from BGR colorspace to HSV colorspace hsv = cv2.cvtColor(card, cv2.COLOR_BGR2HSV) # separate hue, saturation, and value into three images hue, sat, val = [np.array([[col[i] for col in row] for row in hsv]) for i in xrange(3)] # get binary representation of saturation image # higher threshold = less white _, bin_sat = cv2.threshold(np.array(sat), thresh=55, maxval=255, type=cv2.THRESH_BINARY) # bin_sat = cv2.GaussianBlur(bin_sat, ksize=(5, 5), sigmaX=0) # get binary representation of value image # higher threshold = more white _, bin_val = cv2.threshold(np.array(val), thresh=140, maxval=255, type=cv2.THRESH_BINARY_INV) bin_sat_val = cv2.bitwise_or(bin_sat, bin_val) # erosion followed by morphological opening to erase noise and fill gaps # in shapes kernel_e = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2)) kernel_d = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 8)) bin_sat_val = cv2.erode(bin_sat_val, kernel_e) bin_sat_val = cv2.morphologyEx(bin_sat_val, cv2.MORPH_CLOSE, kernel_d) return bin_sat_val, hue, sat, val
def threshold_gradient_strength(self, gradient_mag): """ thresholds the gradient strength such that features are emphasized """ lo, hi = gradient_mag.min(), gradient_mag.max() threshold = lo + self.params['gradient/threshold']*(hi - lo) bw = (gradient_mag > threshold).astype(np.uint8) for _ in xrange(2): bw = cv2.pyrDown(bw) # do morphological opening to remove noise w = 2#0 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (w, w)) bw = cv2.morphologyEx(bw, cv2.MORPH_OPEN, kernel) # do morphological closing to locate objects w = 2#0 bw = cv2.copyMakeBorder(bw, w, w, w, w, cv2.BORDER_CONSTANT, 0) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2*w + 1, 2*w + 1)) bw = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel) bw = bw[w:-w, w:-w].copy() for _ in xrange(2): bw = cv2.pyrUp(bw) return bw
def cleanNoise( img, smallKernal, bigKernal): ###### These steps should clean up some of smaller noise in the image se1 = cv2.getStructuringElement(cv2.MORPH_RECT, smallKernal ) #### create kernel for the morphological operations se2 = cv2.getStructuringElement(cv2.MORPH_RECT, bigKernal ) mask = cv2.morphologyEx(img, cv2.MORPH_CLOSE, se2) #### close = dilation followed by erosion mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, se1) #### open = erosion followed by dilation return( mask )
def find_boxes(img): """ Detects box(square) shapes in the input image. :param img: input image. :return: image with outlines of boxes from the original image. """ kernel_length = np.array(img).shape[1] // 75 verticle_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kernel_length)) hori_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_length, 1)) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # Detect vertical and horizontal lines in the image img_temp1 = cv2.erode(img, verticle_kernel, iterations=2) verticle_lines_img = cv2.dilate(img_temp1, verticle_kernel, iterations=2) img_temp2 = cv2.erode(img, hori_kernel, iterations=2) horizontal_lines_img = cv2.dilate(img_temp2, hori_kernel, iterations=2) # Weighting parameters, this will decide the quantity of an image to be added to make a new image. alpha = 0.5 beta = 1.0 - alpha # Add the vertical and horizontal lines images to get a third image as summation. img_final_bin = cv2.addWeighted(verticle_lines_img, alpha, horizontal_lines_img, beta, 0.0) img_final_bin = cv2.erode(~img_final_bin, kernel, iterations=2) (_, img_final_bin) = cv2.threshold(img_final_bin, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) return img_final_bin
def segmentCellsCanny(image, mincellsize=10, lower=130, upper=255): boundingBoxes = [] gray = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY) gray = blur(gray, 7) gray = erodeAndDilate(gray, 15, 3) cv2.imshow("gray", gray) canny = cv2.Canny(gray, 5, 50) # PLAY AROUND WITH THESE VALUES element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(4,4)) canny = cv2.dilate(canny, element) element1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2,2)) canny = cv2.erode(canny, element1) cv2.imshow("canny", canny) contours, hierarchy = cv2.findContours(canny,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #print type(contours) for contour in contours: contour_area = cv2.contourArea(contour) if contour_area > mincellsize: boundingBoxes.append(cv2.boundingRect(contour)) boxImg = drawBoundingBoxes(image, boundingBoxes) return boundingBoxes, boxImg, canny
def __init__(self): super(Morphology, self).__init__() self._threshold = -1 self._kernel_3x3 = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3), (1, 1)) self._kernel_5x5 = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5), (1, 1)) self._kernel_cross = np.array( [[0,0,1,0,0], [0,0,1,0,0], [1,1,1,1,1], [0,0,1,0,0], [0,0,1,0,0]], dtype=np.uint8) self._kernel_diamond = np.array( [[0,0,1,0,0], [0,1,1,1,0], [1,1,1,1,1], [0,1,1,1,0], [0,0,1,0,0]], dtype=np.uint8) self._kernel_x = np.array( [[1,0,0,0,1], [0,1,0,1,0], [0,0,1,0,0], [0,1,0,1,0], [1,0,0,0,1]], dtype=np.uint8)
def remove_bed(im, bgn): eroelement = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5),(3,3)) # use for dilation dilelement = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,20),(5,10)) # use for erosion diff = cv2.absdiff(bgn,im) t= np.uint8((diff.max()-diff.min())/2) _, mask = cv2.threshold(diff, t, 255, cv2.THRESH_BINARY) # Morphological filters diff = cv2.erode(diff,eroelement,iterations=3) #3 diff = cv2.dilate(diff, dilelement, iterations=7) #5 outImage = np.ones(im.shape, np.uint8) # Find and draw contours (when found) tempContours, hierarchy = cv2.findContours(diff, mode=cv2.RETR_CCOMP, method=cv2.CHAIN_APPROX_SIMPLE) #chain can be NONE for h,cnt in enumerate(tempContours): if len(cnt) <100: tempImage3 = np.ones(im.shape, np.uint8) #cv2.drawContours(tempImage3,[cnt], contourIdx=-1, color=(0,255,0),thickness=-1, maxLevel=0) cv2.drawContours(tempImage3,[cnt], contourIdx=-1, color=(255,255,255),thickness=-1) ## tempImage4 = cv2.cvtColor(tempImage3, cv2.COLOR_BGR2GRAY) outImage = cv2.bitwise_and(im, tempImage3) cv2.drawContours(outImage,[cnt], contourIdx=-1, color=(255,0,0),thickness=1) cv2.imshow("output w contours", outImage) cv2.waitKey(0) #for enumerate return outImage
def __sobel_image__(self,image,horizontal): """ apply the sobel operator to a given image on either the vertical or horizontal axis basically copied from http://stackoverflow.com/questions/10196198/how-to-remove-convexity-defects-in-a-sudoku-square :param horizontal: :return: """ if horizontal: dy = cv2.Sobel(image,cv2.CV_16S,0,2) dy = cv2.convertScaleAbs(dy) cv2.normalize(dy,dy,0,255,cv2.NORM_MINMAX) ret,close = cv2.threshold(dy,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(10,2)) else: dx = cv2.Sobel(image,cv2.CV_16S,2,0) dx = cv2.convertScaleAbs(dx) cv2.normalize(dx,dx,0,255,cv2.NORM_MINMAX) ret,close = cv2.threshold(dx,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(2,10)) close = cv2.morphologyEx(close,cv2.MORPH_CLOSE,kernel) return close
def run(): """Main image masking and publishing code""" global samples_without_find while True: # read frame from webcam _,img = webcam.read() # convert frame to HSV format hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV) # create mask for color selected in color tuning panel mask = cv2.inRange(hsv_img, numpy.array([lowH,lowS,lowV],numpy.uint8),\ numpy.array([highH,highS,highV],numpy.uint8)) # convert mask to binary image format _,binary = cv2.threshold(mask,127,255,cv2.THRESH_BINARY) # filter image to reduce noise binary = cv2.erode(binary,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))) binary = cv2.dilate(binary,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))) center_x = -1 center_y = -1 # get moments of image moments = cv2.moments(binary) if (moments['m00'] > 0.0): samples_without_find = 0 # find the "center of gravity" of the moment # (which is hopefully the tracked object) center_x = int(moments['m10']/moments['m00']) center_y = int(moments['m01']/moments['m00']) update_motors(center_x, center_y) else: samples_without_find += 1 print "Color not found." if samples_without_find > 50: # pivot in place (send bogus coords to robot) update_motors(-1, -1)
def skin_blobs(self, img, det_face_hsv, face_rect, masked_img): """ Do blob morphology stuff on faces. Perform a mask, Then dilate and erode to make them into more coherent blobs. :param img: BGR image from webcam :param det_face_hsv: hsv image of the face from the previous detection :param face_rect: non-normalized dimensions of face rectangle (left, top, cols, rows) :return: 2D array, black and white image of skin blobs """ #open and close # kernel size and shape are more art than science # using a small kernel to erode noise and a large on to # to dilate since I have more false negatives with skin # detection than I do false positives. kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (4, 4)) kernel_small = kernel & np.transpose(kernel) #symmetry kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (6, 6)) kernel_big = kernel & np.transpose(kernel) #symmetry blob_img = cv2.erode(masked_img, kernel_small) blob_img = cv2.dilate(blob_img, kernel_big) blob_img = cv2.erode(blob_img, kernel_small) blob_img = cv2.dilate(blob_img, kernel_big) return blob_img
def squares_from_corner_image(centers): centers = cv2.morphologyEx(centers,cv2.MORPH_DILATE, cv2.getStructuringElement(cv2.MORPH_RECT, (20, 20)),iterations = 1) centers = cv2.morphologyEx(centers,cv2.MORPH_ERODE, cv2.getStructuringElement(cv2.MORPH_RECT, (20, 20)),iterations = 1) contour, hier = cv2.findContours(centers.copy(), cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) centroids = [] for cnt in contour: mom = cv2.moments(cnt) (x,y) = int(mom['m10']/mom['m00']), int(mom['m01']/mom['m00']) #cv2.circle(img,(x,y),4,(0,255,0),-1) centroids.append((x,y)) #for i, (x, y) in enumerate(centroids): # cv2.putText(img, str(i), (x, y + 10), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0,0,255)) dtype = [('x', np.int32), ('y', np.int32)] centroids = np.array(centroids, dtype=dtype) centroids.sort(order="x") centroids = centroids.reshape((9, 9, )) for row in centroids: row.sort(order="y") squares = [] for i, row in enumerate(centroids[:-1]): for j, _ in enumerate(row[:-1]): square = [] for x, y in [(i, j), (i + 1, j), (i + 1, j + 1), (i, j + 1)]: point = centroids[x][y].tolist() #ugly hack to strip type information square.append(point) squares.append(np.array(square)) return squares
def run(self): while True: if (self.frame%10 == 0): self.frame = 1 else: self.frame = self.frame +1 ret, im = self.camera.read() im = cv2.flip(im, 1) self.imOrig = im.copy() self.imNoFilters = im.copy() im = cv2.blur(im, (self.Vars["smooth"], self.Vars["smooth"])) filter_ = self.filterSkin(im) filter_ = cv2.erode(filter_, cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(self.Vars["erode"], self.Vars["erode"]))) filter_ = cv2.dilate(filter_, cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(self.Vars["dilate"], self.Vars["dilate"]))) dilated = filter_.copy() cv2.imshow('dilated',dilated) try: vis,self.fingers, self.direction=findConvexHull().drawConvex(filter_,self.imOrig,self.frame) except: # dilated = self.imOrig vis = self.imOrig common.draw_str(vis, (20, 50), 'No of fingers: ' + str(self.fingers)) common.draw_str(vis, (20, 80), 'Movement of contour:' + str(self.direction)) cv2.imshow('image',vis) if cv2.waitKey(1) == 27: break
def run(): """Main image masking and publishing code""" while True: # read frame from webcam _,img = webcam.read() # update color tuning from control panel #updateHSV() # convert frame to HSV format hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV) # create mask for color selected in color tuning panel mask = cv2.inRange(hsv_img, numpy.array([lowH,lowS,lowV],numpy.uint8),\ numpy.array([highH,highS,highV],numpy.uint8)) # convert mask to binary image format _,binary = cv2.threshold(mask,127,255,cv2.THRESH_BINARY) # filter image to reduce noise binary = cv2.erode(binary,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))) binary = cv2.dilate(binary,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))) #binary = cv2.dilate(binary,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))) #binary = cv2.erode(binary,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))) center_x = -1 center_y = -1 # get moments of image moments = cv2.moments(binary) if (moments['m00'] > 0.0): # find the "center of gravity" of the moment # (which is hopefully the tracked object) center_x = int(moments['m10']/moments['m00']) center_y = int(moments['m01']/moments['m00']) print moments print center_x, ', ', center_y
def _extract_interesting_region(data): """Preprocesses image for frame finding. Steps taken are * Otsu thresholding * small-kernel-area opening to get rid of single/isolated bright pixels which are assumend to be noise * large-kernel-area opening to inverse the effect of the prior opening; this also serves the purpose to connect close bright areas (for the next step). Due to the distinct elongation of the kernel in the x- direction this especially favors horizontal structures. * finding largest connected region :param np.ndarray data: Image as 2D array of type uint8 :returns: Mask as 2D array labeling the "interesting area" in that picture """ assert data.dtype == np.uint8, "Image has wrong dtype." _, buf = cv.threshold(data, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU) # Opening to get rid of noise kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3, 3)) buf = cv.morphologyEx(buf, cv.MORPH_OPEN, kernel, iterations=3) # Closing to get connected area where signal should be kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (31, 7)) buf = cv.morphologyEx(buf, cv.MORPH_CLOSE, kernel, iterations=5) # Find the largest connected component cc = label(buf, neighbors=4, background=0) + 1 largest_component = np.argmax(np.bincount(cc.ravel())[1:]) + 1 return cc == largest_component
def setKernel(self, morphEnum, size): if morphEnum == MorphologyEnumerations.ELLIPSE: self.kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, size) elif morphEnum == MorphologyEnumerations.RECTANGLE: self.kernel = cv2.getStructuringElement(cv2.MORPH_RECT, size) elif morphEnum == MorphologyEnumerations.CROSS: self.kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, size)
def ProcessImage(image, binary_threshold, close_size, open_size): _, img_thresh = cv2.threshold(image, binary_threshold, 250, cv2.THRESH_BINARY) #Perform binary threshold to get black and white cv2.imshow('GRAY', image) #Show Grayscale cv2.imshow('THRESHOLD', img_thresh) #Show binary threshold image # MORPHING # First close the image to get rid of black dots within larger shapes circ_mask = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(close_size,close_size)) img_morph = cv2.morphologyEx(img_thresh, cv2.MORPH_CLOSE, circ_mask) cv2.imshow('CLOSED', img_morph) # Then open to get rid of white elements that are too small to be significant circ_mask = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(open_size,open_size)) img_morph = cv2.morphologyEx(img_morph, cv2.MORPH_OPEN, circ_mask) cv2.imshow('OPENED', img_morph) #CONTOURS img_contours = np.zeros((image.shape[0], image.shape[1],3), np.uint8) #Create empty image #Get contours, with hierarchy so I don't lose nested (child) contours contours, heirarchy = cv2.findContours(img_morph, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) #Get contours #Add each contour with a random color for contour_idx in range(len(contours)): #if not a child contour, draw with random color if heirarchy[0][contour_idx,3] == -1: cv2.drawContours(img_contours, contours, contour_idx, np.random.randint(0,255,3), -1) #if a child contour, just draw as background color else: cv2.drawContours(img_contours, contours, contour_idx, BACKGROUND_COLOR, -1) #Show contoured/colored output cv2.imshow('CONTOURS', img_contours) cv2.waitKey(0) return
def segmentate(self): self.reset() self.scale(2.0) self._img_orig = img_orig = self.img.copy() skew = self.skew(230, 255) if skew is None: print('Retry') skew = self.skew(20, 100) self.reset() #self.scale(2.0, cv2.INTER_NEAREST) self.scale(2.0, cv2.INTER_CUBIC) self.rotate(skew) # _, lev = self.levels(106, 122, 8.58) # th = self.hsv_threshold(lev) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 3)) # closed = cv2.morphologyEx(th, cv2.MORPH_CLOSE, kernel) th = self.threshold(self.gray(self.hsv_levels(0, 172, 0.21, level=2))) closed = cv2.morphologyEx(th, cv2.MORPH_OPEN, kernel) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 8)) closed = cv2.morphologyEx(closed, cv2.MORPH_CLOSE, kernel) #cv2.imshow('closed', closed) #self.scale(2.0, cv2.INTER_NEAREST) #self.scale(0.5, cv2.INTER_CUBIC) self._gray = gray = self.hsv_threshold() self._mask_and = mask_and = cv2.bitwise_and(255-gray, 255-gray, mask=closed) #cv2.imshow('255-mask_and', 255-mask_and) img_scale = cv2.bitwise_and(self.img, self.img, mask=mask_and) #closed) self._cnts, self._img_dbg = Ojooo.detect_contours(img_scale, mask_and)
def findRegions(gray): ''' 输入一张灰度图,输出查找到的单字的矩形位置 ''' kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) # close 去掉噪声 closing = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel2) # 让字的笔画连在一起,好识别 erosion = cv2.erode(closing, kernel1, iterations=2) # 有时候字的笔画接触了边缘,无法正确识别出轮廓,因此要加margin mask = 255 * np.ones((gray.shape[0]+4, gray.shape[1]+4), np.uint8) mask[2:-2, 2:-2] = erosion contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) region = [] # m表示图片的面积 * 0.8 m = gray.shape[0] * gray.shape[1] * 4 / 5 # 轮廓过滤 for i in range(len(contours)): cnt = contours[i] area = cv2.contourArea(cnt) if area < 100 or area > m: continue region.append(cnt) return region
def preprocess(gray): # 1. Sobel算子,x方向求梯度 sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize = 3) # 2. 二值化 ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY) # 3. 膨胀和腐蚀操作的核函数 element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9)) element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6)) # 4. 膨胀一次,让轮廓突出 dilation = cv2.dilate(binary, element2, iterations = 1) # 5. 腐蚀一次,去掉细节,如表格线等。注意这里去掉的是竖直的线 erosion = cv2.erode(dilation, element1, iterations = 1) # 6. 再次膨胀,让轮廓明显一些 dilation2 = cv2.dilate(erosion, element2, iterations = 3) # dilation2 = cv2.dilate(erosion, element1, iterations = 1) # 7. 存储中间图片 cv2.imwrite("temp/gray.png", gray) cv2.imwrite("temp/binary.png", binary) cv2.imwrite("temp/dilation.png", dilation) cv2.imwrite("temp/erosion.png", erosion) cv2.imwrite("temp/dilation2.png", dilation2) return dilation2
def green_carpet_mask(img, lowerb_hls, upperb_hls, ker_erode=None, ker_close=None, ker_erode2=None): """ Find green carpet on image :param img: """ mask = mask_hls(img, lowerb_hls, upperb_hls) if not ker_erode: ker_erode = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(5, 5)) cv2.morphologyEx(mask, op=cv2.MORPH_ERODE, kernel=ker_erode, dst=mask) ret, mask = largest_contour_blob(mask) if ret: cv2.morphologyEx(mask, op=cv2.MORPH_DILATE, kernel=ker_erode, dst=mask) if not ker_close: ker_close = cv2.getStructuringElement(cv2.MORPH_RECT, (33, 33)) # cv2.morphologyEx(mask, cv2.MORPH_DILATE, ker_close, dst=mask) if not ker_erode2: ker_erode2 = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(5, 5)) # return cv2.morphologyEx(mask, op=cv2.MORPH_ERODE, kernel=ker_erode2, # dst=mask) cv2.morphologyEx(mask, op=cv2.MORPH_CLOSE, kernel=ker_erode2, dst=mask, iterations=3) return cv2.morphologyEx(mask, op=cv2.MORPH_ERODE, kernel=ker_erode2, dst=mask, iterations=3) else: return np.zeros_like(mask)
def detect_harris_squares(img): gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray,(3,3),0) gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 3, 2) gray = cv2.morphologyEx(gray,cv2.MORPH_DILATE, cv2.getStructuringElement(cv2.MORPH_RECT, (4, 4)),iterations = 1) gray = cv2.morphologyEx(gray,cv2.MORPH_ERODE, cv2.getStructuringElement(cv2.MORPH_RECT, (4, 4)),iterations = 1) mask, x, y, width, height = get_board_mask(gray) roi = gray[y: y+ height, x: x + width] #result is dilated for marking the corners, not important # Threshold for an optimal value, it may vary depending on the image. dst = roi.copy() rst = cv2.cornerHarris(dst, 5, 1, 0.04) #dst = cv2.dilate(dst, None) width, height = rst.shape dst = cv2.cvtColor(dst, cv2.COLOR_GRAY2BGR) dst_max = rst.max()*0.5 for y in xrange(0, height): for x in xrange(0, width): harris = rst[x][y] # check the corner detector response if harris > dst_max: # draw a small circle on the original image cv2.circle(dst, (x,y), 2, (255, 0, 25))
inputpath="D:/PROJECTS/Python/car video/found7/crop/number/digits/" outputpath="D:/PROJECTS/Python/car video/found7/crop/" #data = binary_blobs(200, blob_size_fraction=.2, volume_fraction=.35, seed=1) img = cv2.imread(inputpath+'-919.jpg-262.jpg-184.jpg-205-13.jpg',0) #img = cv2.imread('sofsk.png',0) size = np.size(img) skel = np.zeros(img.shape,np.uint8) ret,img = cv2.threshold(img,127,255,0) element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3)) done = False while( not done): eroded = cv2.erode(img,element) temp = cv2.dilate(eroded,element) temp = cv2.subtract(img,temp) skel = cv2.bitwise_or(skel,temp) img = eroded.copy() zeros = size - cv2.countNonZero(img) if zeros==size: done = True cv2.imshow("skel",skel) cv2.waitKey(0)
if k == 27: break cap.release() cv2.destroyAllWindows() if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("video", help = "A: Suturing: B: Pizza making") parser.add_argument("type", help = "1: MOG 2: MOG2 3: Ken's algorithm") args = parser.parse_args() cap = None if args.video == 'A': cap = cv2.VideoCapture('/home/animesh/DeepMilestones/jigsaws/Suturing_video/frames/Suturing_E003_capture2/cropped_scaled.avi') elif args.video == 'B': cap = cv2.VideoCapture('/home/animesh/C3D/examples/c3d_feature_extraction/input/frm/pizza8/videos/cropped_scaled.avi') else: print "Invalid video type" sys.exit() if (int(args.type) == 1): params = (500, 10, 0.9, 1) run_video_with_bsub(cap, cv2.BackgroundSubtractorMOG, params = None) elif (int(args.type) == 2): run_video_with_bsub(cap, cv2.BackgroundSubtractorMOG2) elif (int(args.type) == 3): kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) run_video_with_bsub(cap, cv2.createBackgroundSubtractorGMG, kernel = kernel) else: print "Error Type" sys.exit()
def scale(self): hsv = cv.cvtColor(self.img, cv.COLOR_BGR2HSV) frame_threshold = cv.inRange(hsv, (20, 120, 120), (30, 255, 255)) # cv.imshow("treszhold", frame_threshold) kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) closing = cv.morphologyEx(cv.bitwise_not(frame_threshold), cv.MORPH_OPEN, kernel) kernel = cv.getStructuringElement(cv.MORPH_RECT, (20, 20)) closing = cv.morphologyEx(closing, cv.MORPH_OPEN, kernel) self.tape = closing # cv.imshow("miarka", self.tape) img_lines = self.img.copy() krawedzie = cv.Canny(frame_threshold, 50, 150, apertureSize=3) # cv.imshow("kraw", krawedzie) lines_ver = cv.HoughLines(krawedzie, 1, np.pi / 360, 100, None, 0, 0) tape_orientation_ver = lines_ver[0][0][1] tape_orientation_hor = (tape_orientation_ver + np.pi / 2) % np.pi xy_horizontal = [] lines_hor = cv.HoughLines(krawedzie, 1, np.pi / 360, 20, None, 0, 0) if lines_hor is not None: for i in range(0, len(lines_hor)): rho = lines_hor[i][0][0] theta = lines_hor[i][0][1] a = math.cos(theta) b = math.sin(theta) x0 = a * rho y0 = b * rho pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * a)) pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * a)) if (tape_orientation_hor - 0.02) < theta < (tape_orientation_hor + 0.02): cv.line(img_lines, pt1, pt2, (0, 0, 255), 3, cv.LINE_AA) xy_horizontal.append((x0, y0)) xy_horizontal.sort(key=takeSecond) xy_horizontal_uniques = [] xy_horizontal_uniques.append(xy_horizontal[0]) for i in range(1, len(xy_horizontal) - 1): distance = dist.euclidean( (xy_horizontal[i - 1][0], xy_horizontal[i - 1][1]), (xy_horizontal[i][0], xy_horizontal[i][1])) if math.fabs(distance) > 12: xy_horizontal_uniques.append(xy_horizontal[i]) delta_y = [] for i in range(0, len(xy_horizontal_uniques) - 1): distance = dist.euclidean( (xy_horizontal_uniques[i][0], xy_horizontal_uniques[i][1]), (xy_horizontal_uniques[i + 1][0], xy_horizontal_uniques[i + 1][1])) delta_y.append(math.fabs(distance)) pixel_per_cm = np.median(delta_y) pixel_per_mm = pixel_per_cm / 10 mm_per_pixel = 1 / pixel_per_mm self.index = mm_per_pixel
def get(): if request.method == 'POST': url = request.args.get(key='imagelink') req = urlopen(url) arr = np.asarray(bytearray(req.read()), dtype=np.uint8) img = cv2.imdecode(arr, -1) # 'Load it as it is' # Load image original = img.copy() # Original Image copy # Image Processing gamma = 0.8 invGamma = 1 / gamma table = np.array([((i / 255.0)**invGamma) * 255 for i in np.arange(0, 256)]).astype("uint8") cv2.LUT(img, table, img) img = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #To grayscale img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 12) #To binary img = np.invert(img) #Invert img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, cv2.getStructuringElement( cv2.MORPH_RECT, (3, 3))) #Closing contours, hier = cv2.findContours( img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #Find all contours biggest_area = 0 biggest_contour = None for i in contours: area = cv2.contourArea(i) if area > biggest_area: biggest_area = area biggest_contour = i if biggest_contour is None: sys.exit(1) mask = np.zeros((img.shape), np.uint8) cv2.drawContours(mask, [biggest_contour], 0, (255, 255, 255), -1) img = cv2.bitwise_and(img, mask) grid = original.copy() cv2.drawContours(grid, [biggest_contour], 0, (255, 0, 255), 3) contours, hier = cv2.findContours( img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #Find all contours c = 0 grid = original.copy() average_cell_size = biggest_area / 81 bound_range = 4 lower_bound = average_cell_size - average_cell_size / bound_range upper_bound = biggest_area / 81 + average_cell_size / bound_range cells = [] x, y, w, h = cv2.boundingRect(biggest_contour) epsilon = 0.1 * cv2.arcLength(biggest_contour, True) approx = cv2.approxPolyDP(biggest_contour, epsilon, True) cv2.drawContours(grid, [approx], 0, (255, 255, 0), 3) for i in contours: area = cv2.contourArea(i) if area >= lower_bound and area <= upper_bound: cv2.drawContours(grid, contours, c, (0, 255, 0), 3) cells.append(i) c += 1 bx, by, bw, bh = cv2.boundingRect(biggest_contour) aw = int(bw / 9) ah = int(bh / 9) awb = int(aw / 4) ahb = int(aw / 4) tabla = np.zeros((9, 9)) dataList = [] if len(cells) == 81: for i in range(9): for j in range(9): x = [0, int(bx - awb + j * aw), int(bx + bw)] y = [0, int(by - ahb + i * ah), int(by + bh)] x.sort() y.sort() x = x[1] y = y[1] crop = img[y:by + ah + ahb + i * ah, x:bx + aw + awb + j * aw] cont, hier = cv2.findContours(crop, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) bsize = 0 bcont = None bindex = None for c in range(len(cont)): area = cv2.contourArea(cont[c]) if area > bsize: bsize = area bcont = cont[c] bindex = c if bcont is None: sys.exit(1) else: secondbsize = 0 secondbcont = None for c in range(len(cont)): if hier[0][c][3] == bindex: area = cv2.contourArea(cont[c]) if area > secondbsize: secondbsize = area secondbcont = cont[c] if secondbcont is None: sys.exit(2) mask = np.zeros((crop.shape), np.uint8) cv2.drawContours(mask, [secondbcont], 0, (255, 255, 255), -1) finetune = cv2.bitwise_and(crop, mask) x, y, w, h = cv2.boundingRect(secondbcont) finetune = finetune[y + 3:y + h - 3, x + 3:x + w - 3] finetune = cv2.morphologyEx( finetune, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))) finetune = np.invert(finetune) kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]]) finetune = cv2.filter2D(finetune, -1, kernel) finetune = cv2.resize(finetune, (0, 0), fx=3, fy=3) finetune = cv2.GaussianBlur(finetune, (11, 11), 0) finetune = cv2.medianBlur(finetune, 9) data = pytesseract.image_to_string( finetune, lang='eng', config= '--psm 10 --oem 3 -c tessedit_char_whitelist=123456789' ) dataList = dataList + re.split(r',|\.|\n| ', data) number = re.findall('\d+', data) if not re.findall('\d+', data): tabla[i, j] = 0 else: tabla[i, j] = number[0] else: sys.exit(1) numpyData = {"array": tabla} encodedNumpyData = json.dumps(numpyData, cls=NumpyArrayEncoder) return encodedNumpyData
def processVideo( video_file, width, height, length, demo=False ) -> List[List[Tuple[Tuple[int, int], Tuple[int, int], Tuple[int, int], Tuple[ int, int]]]]: """ Get non-background bounding boxes every frame by GMG algorithm. Some initial filtering is used to filter boxes too small, (smaller than 100 square pixels) in the meantime, both background and contours are extracted and cached for later use. :return: boxes """ allContrours = [] allBoxes, caching = retrieveComputed() if allBoxes is None or demo: allBoxes = [] caching = True else: return allBoxes assert os.path.isfile(video_file), "video file not found" video = cv2.VideoCapture(video_file) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) fgbg = cv2.bgsegm.createBackgroundSubtractorGMG() width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) length = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) demoFrame = np.full((height * 2, width * 2, 3), 255, dtype=np.uint8) boxImages = dict() backgroundFrequencies = [[dict() for _ in range(width)] for _ in range(height)] background = np.full((height, width, 3), 255, dtype=np.uint8) counter = 0 sampling_min = int(0.136 * length) sampling_max = int(0.2 * length) while 1: ret, frame = video.read() print("Video processing progress: %d\r" % ((counter + 1) * 100 / length), end="") if ret: frameBoxes = [] frameContours = dict() fgmask = fgbg.apply(frame) fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel) _, th1 = cv2.threshold(fgmask, 127, 255, cv2.THRESH_BINARY) a, contours, *_ = cv2.findContours( th1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # showing the masked result # if counter // 50 == 0: if sampling_min <= counter <= sampling_max: bgmask = np.logical_not(fgmask) # cv2.waitKey() bg = cv2.bitwise_and(frame, frame, mask=bgmask.astype(np.uint8)) if demo: demoFrame = createCenteredDemoFrame( bg, "Processing Video: %d%%" % ((counter + 1) * 100 / length), "sampling background", ) for r in range(height): for c in range(width): if bgmask[r][c]: p = tuple(bg[r][c]) k = backgroundFrequencies[r][c] if p in k: k[p] += 1 else: k[p] = 1 elif demo: showingFrame = np.full((height, width, 3), 255, dtype=np.uint8) demoFrame = createCenteredDemoFrame( showingFrame, "Processing Video: %d%%" % ((counter + 1) * 100 / length), "", ) if demo: cv2.imshow("demo", demoFrame) DEMO_FRAMES.append(demoFrame) cv2.waitKey(1) for i in range(len(contours)): if len(contours[i]) >= 5: # geting the 4 points of rectangle x, y, w, h = cv2.boundingRect(contours[i]) if w * h >= 100: # upper-left upper-right lower-left lower-right box = ((x, y), (x + w, y), (x, y + h), (x + w, y + h)) frameBoxes.append(box) boxImages[(counter, ) + box] = frame[y:y + h, x:x + w] frameContours[box] = contours[i] allContrours.append(frameContours) allBoxes.append(frameBoxes) else: break counter += 1 print("Video processing progress: 100") video.release() for r in range(height): for c in range(width): px = tuple(backgroundFrequencies[r][c].items()) if px: maxP = max(tuple(backgroundFrequencies[r][c].items()), key=lambda x: x[1])[0] else: maxP = (255, 255, 255) background[r][c] = maxP if caching: if not os.path.exists("cached"): os.makedirs("cached") filename = os.path.join("cached", "trafficVideoBoxes.pickle") contoursFilename = os.path.join("cached", "contours.pickle") backgroundFilename = os.path.join("cached", "background.jpg") boxImagesFilename = os.path.join("cached", "boxImages.pickle") with open(filename, "wb") as file: pickle.dump(allBoxes, file) with open(contoursFilename, "wb") as file: pickle.dump(allContrours, file) with open(boxImagesFilename, "wb") as file: pickle.dump(boxImages, file) # print(background[0:10, 0:10]) cv2.imwrite(backgroundFilename, background) print( "bounding boxes, contours, extracted background cached for later use" ) print("video frame count: %d" % length) return allBoxes
def castom(self): #wl = (0,50,0) #wh = (50,100,255) buff = 0 self.wl = (15,0,165) self.wh = (25,255,255) self.ret, self.frame = self.capture.read() self.hsv = cv2.cvtColor(self.frame, cv2.COLOR_BGR2HSV) self.h,self.s,self.v = cv2.split(self.hsv) for i in range(len(self.s)): for j in range(len(self.s[0])): buff += self.s[i][j] count = len(self.s) * len(self.s[0]) Smiddle = buff / count #print("SMIDDLE = {}".format(round(Smiddle, 1))) light = ((256 - (buff / count)) / 256) * 100 print("LIGHT = {}%".format(round(light, 1))) #print(self.v) #hsv = cv2.GaussianBlur(hsv, (3, 3), 0) cv2.imshow('hsv', self.hsv) self.w = cv2.inRange(self.hsv,self.wl,self.wh) #b,g,r = cv2.split(hsv) #ret,thresh = cv2.threshold(self.w,50,255,cv2.THRESH_BINARY_INV) canny = cv2.Canny(self.w, 10, 100) #edged = cv2.Canny(gray, 10, 250) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) closed = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel) _, cnts, hierarchy = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) #for cur_contours in contours: # pass for c in cnts: #print("c is {}".format(c)) #print("len c is {}".format(len(c))) #print("rect = {}".format(rect)) #area = int(rect[1][0]*rect[1][1]) # аппроксимируем (сглаживаем) контур peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) #cv2.drawContours(self.frame, approx, -1, (255, 255, 0), 5) square = isitsquare(approx) if square: rect = cv2.minAreaRect(c) #print("RECT = {}".format(rect)) box = cv2.boxPoints(rect) box = np.int0(box) #print("BOX = {}".format(box)) #hill = cv2.convexHull(c) #print("approx is {}".format(approx)) #cv2.drawContours(self.frame, [box], -1, (0, 255, 255), 5) cv2.drawContours(self.frame, [approx], -1, (0, 255, 0), 2) #cv2.drawContours(self.frame, hill, -1, (0, 255, 255), 5) #cv2.imshow('castom', self.w) #cv2.imshow('something', thresh) cv2.imshow('closed', closed) cv2.imshow('release', self.frame)
def extract_text(input_image, max_contour_area=1000, max_contour_envelope_area=1500, aspect_ratio=2.0, gblur="True", erode="True"): """ These are Gina`s default values for the params :param input_image: :param max_contour_area: controls rejection of contours :param max_contour_envelope_area: controls rejection of contours :param aspect_ratio: controls rejection of contours :param gblur: apply gaussian blur :param erode: apply erosion filter :return: """ print("Hey remember, we`ve turned off most of the script! :)") job_uuid = str(uuid.uuid4()) base_output_path = "/home/james/geocrud/adrc/" print("processing %s" % input_image) fname_timestamp = time.strftime("%Y%m%d-%H%M%S") # Load map – change path and filename # cv2.imread(filename) : loads an image from a file - returns an array/matrix im = cv2.imread(input_image) # im.copy() : copies one array to another im2 = im.copy() #keep a copy im3 = im.copy() #print "input image..." # cv2.imshow(winname, image) : display an image in the specified window #cv2.imshow("1 Input Image", im) # cv2.waitKey(delay in ms) : wait for a key event #cv2.waitKey(0) ############################ PRE-PROCESSING ############################## # Convert to greyscale processed_image = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY) #cv2.imshow("2 Greyscaled", processed_image) #cv2.waitKey(0) # Apply Gaussian Blur - Increase in case of dotted background if gblur == "True": processed_image = cv2.GaussianBlur(processed_image, (5, 5), 0) #cv2.imshow("3 GBlur Applied", processed_image) #cv2.waitKey(0) # Apply Otsu's threshold and invert the colors of the image - digits white on black background (thresh, processed_image) = cv2.threshold(processed_image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) #cv2.imshow("4 Thresholded", processed_image) #cv2.waitKey(0) if erode == "True": # Define Kernel Size and apply erosion filter element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) processed_image = cv2.erode(processed_image, element) blank = processed_image.copy() blank2 = blank.copy() processed_image_b = processed_image.copy() #print "erosion filter applied..." #cv2.imshow("5 Erosion Filter applied", processed_image) #cv2.waitKey(0) out_fname = "".join([ base_output_path, # job_uuid, # "_", # str(max_contour_area), # "_", # str(max_contour_envelope_area), # "_", # str(aspect_ratio), "img_passed_to_feature_extraction.tif" ]) cv2.imwrite(out_fname, processed_image) ############################ FEATURE DETECTION ############################## # Contour tracing - Detect all contours with no hierarchy image, contours, hierarchy = cv2.findContours(processed_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) #################### JRCC - SHOW ALL Contours ############################# font = cv2.FONT_HERSHEY_COMPLEX # draw mbr of every contour id = 0 num_retained = 0 num_dropped = 0 lower_area_threshold = 0 contour_features = [] final_contours = [] contours_retain = [] # thresholds to decide if we retain the contour thresholds = { "area": 5000, "h_lower": 20, "h_upper": 100, "aspect_ratio": 1.5, "roundness": 0.1, "solidity": 0.8 } base_outfname = os.path.splitext(os.path.split(input_image)[-1])[0] #out_fname = os.path.join("/home/james/geocrud/adrc", "".join([base_outfname, "_contour_properties.csv"])) #with open(out_fname, "w") as outpf: # my_writer = csv.writer(outpf, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC) # my_writer.writerow(["id", "x", "y", "w", "h", "area", "perimeter", "is_convex", "angle_of_rotation", "aspect_ratio", "extent", "solidity", "compactness", "roundness"]) for cnt in contours: this_contour_properties = get_contour_properties(cnt) x = this_contour_properties["x"] y = this_contour_properties["y"] w = this_contour_properties["w"] h = this_contour_properties["h"] # hw = h/w # wh = w/h # area = this_contour_properties["area"] # perimeter = this_contour_properties["perimeter"] # is_convex = this_contour_properties["is_convex"] # angle_of_rotation = this_contour_properties["angle_of_rotation"] # aspect_ratio = this_contour_properties["aspect_ratio"] # extent = this_contour_properties["extent"] # solidity = this_contour_properties["solidity"] # compactness = this_contour_properties["compactness"] # roundness = this_contour_properties["roundness"] if retain_contour(this_contour_properties, thresholds): cv2.rectangle(im2, (x, y), (x + w, y + h), (0, 255, 0), 1) #cv2.putText(im2, str(id), (x, y+h), cv2.FONT_HERSHEY_PLAIN, 2, [0,0,255]) contours_retain.append(cnt) num_retained += 1 else: num_dropped += 1 #if area > lower_area_threshold: #cv2.rectangle(im2, (x, y), (x + w, y+h), (0, 255, 0), 1) #cv2.putText(im2, str(id), (x, y+h), cv2.FONT_HERSHEY_PLAIN, 2, [0,0,255]) #contour_features.append([id, x, y, w, h]) #my_writer.writerow([id, w, h, hw, wh, area, perimeter, is_convex, angle_of_rotation, aspect_ratio, extent, solidity, compactness, roundness]) #final_contours.append(cnt) #num_retained += 1 #else: #num_dropped += 1 id += 1 #dump_contours_to_shapefile(contour_features, input_image) #cv2.drawContours(im2, final_contours, -1, (255, 64, 0), 1) #cv2.drawContours(processed_image, final_contours, -1, (255, 64, 0), 1) #cv2.imwrite(out_fname, processed_image) #print "num contours retained", num_retained #print "num contours dropped", num_dropped cv2.imwrite("/home/james/geocrud/adrc/82877433_selected_contours.tif", im2) ########################################################################### #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!# ########################################################################### # 050416 stop this part of the script running ########################################################################### cont = False if cont: contour_properties = [[ "contour_id", "h", "w", "area", "hw", "wh", "hxw", "x", "y" ]] # display info about every contour and add a label to the displayed image contour_id = 1 for cnt in contours: [x, y, w, h] = cv2.boundingRect(cnt) # cv2.contourArea(contour) : compute contour area contour_area = cv2.contourArea(cnt) hw = h / w wh = w / h hxw = h * w text_x = x text_y = y + h + 15 contour_properties.append( [contour_id, h, w, contour_area, hw, wh, hxw, x, y + h]) #print input_image,contour_id, h, w, hw, wh, contour_area, hxw, x, y+h contour_id += 1 csv_fname = "".join([ base_output_path, # job_uuid, # "_", # str(max_contour_area), # "_", # str(max_contour_envelope_area), # "_", # str(aspect_ratio), "contour_properties.csv" ]) with open(csv_fname, "w") as outpf: c = csv.writer(outpf, delimiter=",", quotechar='"', quoting=csv.QUOTE_NONNUMERIC) c.writerows(contour_properties) out_fname = "".join([ base_output_path, # job_uuid, # "_", # str(max_contour_area), # "_", # str(max_contour_envelope_area), # "_", # str(aspect_ratio), "all_contours.png" ]) # cv2.imwrite() : save image to a specified file cv2.imwrite(out_fname, im2) #print "All contours..." #cv2.imshow("All contours", im2) #cv2.waitKey(0) #################### End of jrcc ########################################## # Apply the first 4 rules for digit graphic separation contours_reject = [] for cnt in contours: [x, y, w, h] = cv2.boundingRect(cnt) if cv2.contourArea( cnt ) < max_contour_area and h / w < aspect_ratio and w / h < aspect_ratio and h * w < max_contour_envelope_area: continue else: contours_reject.append(cnt) # Erase contours from the image cv2.drawContours(blank, contours_reject, -1, (0, 0, 0), -1) #print "Contours Erased..." #cv2.imshow("Contours Erased", blank) #cv2.waitKey(0) #blank2=blank.copy() image, contours, hierarchy = cv2.findContours(blank, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contour_id = 1 contours_retain = [] contours_reject = [] for cnt in contours: if cv2.contourArea(cnt) > 50: contours_retain.append(cnt) else: contours_reject.append(cnt) contour_id += 1 # Erase small contours from the image cv2.drawContours(blank2, contours_reject, -1, (0, 0, 0), -1) #TODO draw the full contour rather than it`s MBR #cv2.drawContours(im2, contours_retain, -1, (0,255,0), 2) #cv2.drawContours(im2, contours_retain, -1, (0,255,0), 2) #cv2.imwrite(out_fname, im2) #print "Small contours erased..." #cv2.imshow("Small Contours Erased", blank2) #cv2.waitKey(0) ############# Dealing with Touching Digits ########################## """ Stavropoulou_Optical Character Recognition on Scanned Maps compressed.pdf p20 num_cols - choice depends on the size of the touching characters and subsequently on the size of the font. After the white pixels have been counted for each column the characters are seperated in the column that has the minimum number of white pixels """ # 070416 - from running against 82877433.tif large important letters # at the start of words are being incorrectly split by this part of # the process due to the w>2*num_cols+1 and w>1.2*h criteria deal_w_touching_digits = False if not deal_w_touching_digits: print( "Hey, one more thing, we`ve turned off dealing with touching digits!" ) #print '.....Dealing with Touching Digits' bounding_list = [] digit_im_list = [] # Set the dimensions for resizing dim = (24, 42) # Specify the search number of columns for selecting cut column. num_cols = 5 for cnt in contours_retain: [x, y, w, h] = cv2.boundingRect(cnt) #finding bounding rectangle if deal_w_touching_digits: if w > 2 * num_cols + 1: if w > 1.2 * h: #in case of fused characters middle = int(round(w / 2)) fused_character_im = blank2[y - 1:y + h + 1, x - 1:x + w + 1] min_col = 0 col_wh_pixels = [] for i in range(middle - num_cols, middle + num_cols): # examining all the middle columns col = fused_character_im[:, i] white_pixels = 0 for j in range(len(col)): if col[j] != 0: white_pixels = white_pixels + 1 col_wh_pixels.append(white_pixels) min_index = col_wh_pixels.index(min(col_wh_pixels)) patch1 = blank2[y - 1:y + h + 1, x - 1:x + middle - num_cols + min_index] resized1 = cv2.resize(patch1, dim, interpolation=cv2.INTER_AREA) ret, patch1 = cv2.threshold(resized1, 50, 255, cv2.THRESH_BINARY) #Repeat thresholding after interpolation patch2 = blank2[y - 1:y + h + 1, x + middle - num_cols + min_index:x + w + 1] resized2 = cv2.resize(patch2, dim, interpolation=cv2.INTER_AREA) ret, patch2 = cv2.threshold(resized2, 50, 255, cv2.THRESH_BINARY) #Repeat thresholding after interpolation digit_im_list.append(patch1) digit_im_list.append(patch2) bounding_list.append([x, y, w / 2, h]) bounding_list.append([x + w / 2, y, w / 2, h]) else: patch = blank2[y - 1:y + h + 1, x - 1:x + w + 1] resized = cv2.resize(patch, dim, interpolation=cv2.INTER_AREA) ret, patch = cv2.threshold(resized, 127, 255, cv2.THRESH_BINARY) #Repeat thresholding after interpolation digit_im_list.append(patch) bounding_list.append([x, y, w, h]) else: # if we`re not dealing with touching digits do the default always # as later on the script makes use of data structures updated here patch = blank2[y - 1:y + h + 1, x - 1:x + w + 1] resized = cv2.resize(patch, dim, interpolation=cv2.INTER_AREA) ret, patch = cv2.threshold(resized, 127, 255, cv2.THRESH_BINARY) #Repeat thresholding after interpolation digit_im_list.append(patch) bounding_list.append([x, y, w, h]) arr = np.array(bounding_list) # TODO - the aoi`s clip too tightly to the contour so we need to add a buffer # 250416 - what was I thinking when I implemented this? # for m in xrange(len(arr)): # x1 = arr[m, 0] # y1 = arr[m, 1] # w = arr[m, 2] # h = arr[m, 3] # x2 = x1 + w # y2 = y1 + h # # # add a 1px buffer around the contour # # errors will happen if the buffer extends beyond the extents of the image # x1 = x1 - 10 # y1 = y1 - 10 # x2 = x2 + 10 # y2 = y2 + 10 # # aoi_fname = base_output_path + str(m) + ".png" # cv2.imwrite(aoi_fname, processed_image_b[y1:y2, x1:x2]) processed_image_c = cv2.cvtColor(processed_image_b, cv2.COLOR_GRAY2RGB) #id = 0 #for m in xrange(len(arr)): #print m #cv2.rectangle(im3,(arr[m,0],arr[m,1]),(arr[m,0] + arr[m,2],arr[m,1]+arr[m,3]),(255,0,255),2) #cv2.rectangle(im3,(int(arr[m,0]),int(arr[m,1])),(int(arr[m,0]) + int(arr[m,2]),int(arr[m,1])+int(arr[m,3])),(255,0,255),2) #cv2.rectangle(processed_image_c,(int(arr[m,0]),int(arr[m,1])),(int(arr[m,0]) + int(arr[m,2]),int(arr[m,1])+int(arr[m,3])),(255,0,255),1) #cv2.putText(processed_image_c, str(id), (int(arr[m,0]),int(arr[m,1])), cv2.FONT_HERSHEY_PLAIN, 2, [0,0,255]) #id += 1 #cv2.imshow("Detected Features", im3) #cv2.waitKey(0) #out_fname = "".join([base_output_path, # job_uuid, # "_", # str(max_contour_area), # "_", # str(max_contour_envelope_area), # "_", # str(aspect_ratio), # "_final_contours.png"]) #cv2.imwrite(out_fname, im3) #cv2.putText(processed_image_c, "Hello World", (10, 10), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0] ) cv2.drawContours(processed_image_c, contours_retain, -1, (0, 255, 0), 2) out_fname = "".join([ base_output_path, # job_uuid, # "_", # str(max_contour_area), # "_", # str(max_contour_envelope_area), # "_", # str(aspect_ratio), "img_passed_to_feature_extraction_w_contours.png" ]) cv2.imwrite(out_fname, processed_image_c) # write out the numpy arrays of the extracted features to a text file # in a seperate script we will classify these id = 0 features = [] for m in range(len(arr)): try: feature = digit_im_list[m] # ------------------------ 250416 --------------------------------- out_fname = "/home/james/geocrud/adrc/" + str(id) + "_sample.png" cv2.imwrite(out_fname, feature) # ------------------------ 250416 --------------------------------- #out_fname = "/home/james/geocrud/adrc/" + job_uuid + "_candidate_" + str(id) + ".png" #out_fname = "/home/james/geocrud/adrc/" + str(id) + ".png" #cv2.imwrite(out_fname, feature) reshaped_feature = feature.reshape((1, 1008)) features.append(reshaped_feature) id += 1 except Exception as ex: print(ex) ########################################################################### #TODO - so we can create a shapefile showing marked up locations we need #to dump location of candidates print("".join(["len(digit_im_list): ", str(len(digit_im_list))])) print("".join(["len(bounding_list): ", str(len(bounding_list))])) id = 0 with open("/home/james/geocrud/adrc/candidate_locations.csv", "w") as outpf: my_writer = csv.writer(outpf, delimiter=",", quotechar='"', quoting=csv.QUOTE_NONNUMERIC) my_writer.writerow(["id", "x", "y", "w", "h"]) for m in range(len(arr)): x, y, w, h = bounding_list[m] my_writer.writerow([id, x, y, w, h]) id += 1 candidates = np.empty((0, 1008)) for feature in features: try: candidates = np.append(candidates, feature, 0) except Exception as ex: print(ex) np.savetxt(os.path.join(base_output_path[:-1], "candidates.data"), candidates)
import cv2 import numpy as np # Load image, grayscale, Otsu's threshold image = cv2.imread('1.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] # Perform morphological hit or miss operation kernel = np.array([[-1,-1,-1], [-1,1,-1], [-1,-1,-1]]) dot_mask = cv2.filter2D(thresh, -1, kernel) # Bitwise-xor mask with binary image to remove dots result = cv2.bitwise_xor(thresh, dot_mask) # Dilate to fix damaged text pixels # since the text quality has decreased from thresholding # then bitwise-and with input image kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2)) dilate = cv2.dilate(result, kernel, iterations=1) result = cv2.bitwise_and(image, image, mask=dilate) result[dilate==0] = [255,255,255] cv2.imshow('dot_mask', dot_mask) cv2.imshow('thresh', thresh) cv2.imshow('result', result) cv2.imshow('dilate', dilate) cv2.waitKey()
def CCT_extract1(img,N,R): #存放解码结果的list CodeTable=[] ''' image.shape[0], 图片垂直尺寸 image.shape[1], 图片水平尺寸 image.shape[2], 图片通道数 ''' img_shape=img.shape img_height=img_shape[0] img_width=img_shape[1] # print('img_width=',img_width) # print('img_height=',img_height) #将输入图像转换为灰度图 img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #使用Otsu对图像进行自适应二值化 retval,img_bina=cv2.threshold(img_gray,0,1,cv2.THRESH_BINARY+cv2.THRESH_OTSU) #使用findcontours函数对二值化后的图像进行轮廓提取,第三个参数为轮廓点的存储方式,这里选返回所有轮廓点,方便后面做筛选 contours, hierarchy = cv2.findContours(img_bina,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE) #cv2.drawContours(img,contours,-1,(0,0,255),1) #遍历提取出来的轮廓,筛选其中的椭圆轮廓 for contour in contours: area=cv2.contourArea(contour,False) length=cv2.arcLength(contour,True) #计算轮廓的圆度 R0=2*math.sqrt(math.pi*area)/(length+1) if R0<R: continue if len(contour)<20: continue #在原图上绘制该条轮廓 # cv2.drawContours(img,contour,-1,(0,0,255),2) # print('det_r=',det_r) # print('len(contour)=',len(contour)) #将轮廓点集转换为numpy数组 e_points=np.array(contour) #得到拟合的椭圆参数:中心点坐标,尺寸,旋转角 box1=cv2.fitEllipse(e_points) #print('box1:',box1) box2=tuple([box1[0],tuple([box1[1][0]*2,box1[1][1]*2]),box1[2]]) box3=tuple([box1[0],tuple([box1[1][0]*3,box1[1][1]*3]),box1[2]]) #求得最外层椭圆的最小外接矩形的四个顶点,顺时针方向 minRect = cv2.boxPoints(box3) #计算椭圆的长轴 a=max(box3[1][0],box3[1][1]) s=1.33333*a #在原图像中裁剪CCT所在的区域 cct_roi=None row_min=round(box1[0][1]-s/2) row_max=round(box1[0][1]+s/2) col_min=round(box1[0][0]-s/2) col_max=round(box1[0][0]+s/2) # print('判断该ROI是否超出边界......') # print([row_min,row_max,col_min,col_max]) #判断cct_roi是否超出原图像边界 if row_min>=0 and row_max<=img_height and col_min>=0 and col_max<=img_width: #从原图像中将cct_roi截取出来 cct_roi=img[row_min:row_max,col_min:col_max] #cct_roi相对于原始影像的偏移量 dx=box1[0][0]-s/2 dy=box1[0][1]-s/2 #对CCT椭圆区域进行仿射变换将其变为正圆 src=np.float32([[minRect[0][0]-dx,minRect[0][1]-dy],[minRect[1][0]-dx,minRect[1][1]-dy], [minRect[2][0]-dx,minRect[2][1]-dy],[minRect[3][0]-dx,minRect[3][1]-dy], [box1[0][0]-dx,box1[0][1]-dy]]) dst=np.float32([[box1[0][0]-a/2-dx,box1[0][1]-a/2-dy],[box1[0][0]+a/2-dx,box1[0][1]-a/2-dy], [box1[0][0]+a/2-dx,box1[0][1]+a/2-dy],[box1[0][0]-a/2-dx,box1[0][1]+a/2-dy], [box1[0][0]-dx,box1[0][1]-dy]]) #得到仿射变换矩阵 #M=cv2.getAffineTransform(src,dst) M=my_getAffineTransform(src,dst) if isinstance(M,int): continue #计算仿射变换后的中心点坐标 X0,Y0=PointAffineTransform(M,[box1[0][0]-dx,box1[0][1]-dy]) #print('X0=',X0,' ','Y0=',Y0) CCT_img=None #对cct_roi进行仿射变换 cct_roi_size=np.shape(cct_roi) if cct_roi_size[0]>0 and cct_roi_size[1]>0: CCT_img=cv2.warpAffine(cct_roi,M,(round(s),round(s))) #print('cct img shape=',np.shape(CCT_img)) #对仿射变换后的CCT进行缩放 CCT_large = cv2.resize(CCT_img, (0, 0), fx=200.0/s, fy=200.0/s, interpolation=cv2.INTER_LANCZOS4) #将放大后的CCT转换为灰度图 CCT_gray=cv2.cvtColor(CCT_large,cv2.COLOR_BGR2GRAY) # #对该灰度图进行自适应二值化 retval,CCT_bina=cv2.threshold(CCT_gray,0,1,cv2.THRESH_BINARY+cv2.THRESH_OTSU) kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) # #执行腐蚀 CCT_eroded=cv2.erode(CCT_bina,kernel) #plt.imshow(CCT_bina) #plt.show() #判断这个区域里是不是CCT if CCT_or_not(CCT_eroded): # print('len(contour)=',len(contour)) # print('a=',box3[1][0]/3) # print('b=',box3[1][1]/3) # print('s=',s) # print('R0=',R0) #调用解码函数进行解码 code=CCT_Decode(CCT_eroded,N) CodeTable.append([code,box1[0][0],box1[0][1]]) # print([code,box1[0][0],box1[0][1]]) #将编码在原图像中绘制出来.各参数依次是:图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细 cv2.putText(img,str(code),(int(box3[0][0]-0.25*s),int(box1[0][1]+0.5*s)),cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2) #绘制拟合出的椭圆 cv2.ellipse(img,box1,(0,255,0),1) cv2.ellipse(img,box2,(0,255,0),1) cv2.ellipse(img,box3,(0,255,0),1) return CodeTable,img
def prediction2(self, frame_crop): is_warning = False silvery_lower = np.array([0, 0, 150]) silvery_upper = np.array([180, 30, 200]) red_lower_1 = np.array([156, 70, 70]) red_upper_1 = np.array([180, 255, 255]) red_lower_2 = np.array([0, 80, 140]) red_upper_2 = np.array([34, 255, 255]) blue_lower = np.array([100, 80, 30]) blue_upper = np.array([124, 255, 255]) w = frame_crop.shape[1] h = frame_crop.shape[0] h_w_ratio = h / w if 0.5 <= h_w_ratio <= 2: crop_hsv = cv2.cvtColor(frame_crop, cv2.COLOR_BGR2HSV) frame_p = cv2.GaussianBlur(frame_crop, (5, 5), 0) mask = cv2.inRange(crop_hsv, silvery_lower, silvery_upper) mask = cv2.erode(mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations=2) mask = cv2.dilate(mask, cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (5, 5)), iterations=2) mask = cv2.medianBlur(mask, 5) mask_r = cv2.inRange(crop_hsv, red_lower_1, red_upper_1) mask_r_2 = cv2.inRange(crop_hsv, red_lower_2, red_upper_2) mask_r = cv2.bitwise_or(mask_r, mask_r_2) mask_r = cv2.erode(mask_r, cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (3, 3)), iterations=2) mask_r = cv2.dilate(mask_r, cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (7, 7)), iterations=2) mask_r = cv2.medianBlur(mask_r, 5) mask_b = cv2.inRange(crop_hsv, blue_lower, blue_upper) mask_b = cv2.erode(mask_b, cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (3, 3)), iterations=2) mask_b = cv2.dilate(mask_b, cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (7, 7)), iterations=2) mask_b = cv2.medianBlur(mask_b, 5) res = cv2.bitwise_and(frame_p, frame_p, mask=mask) res_red = cv2.bitwise_and(frame_p, frame_p, mask=mask_r) res_blue = cv2.bitwise_and(frame_p, frame_p, mask=mask_b) cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] cnts_red = cv2.findContours(mask_r.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] cnts_blue = cv2.findContours(mask_b.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] count_silvery = 0 count_blue = 0 count_red = 0 for c in cnts: area = cv2.contourArea(c) x1, y1, w1, h1 = cv2.boundingRect(c) if area > 2000: count_silvery = count_silvery + 1 cv2.rectangle(res, (x1, y1), (x1 + w1, y1 + h1), (0, 255, 0), 2) for c in cnts_blue: area = cv2.contourArea(c) x1, y1, w1, h1 = cv2.boundingRect(c) if area > 1250: count_blue = count_blue + 1 cv2.rectangle(res_blue, (x1, y1), (x1 + w1, y1 + h1), (255, 0, 0), 2) for c in cnts_red: area = cv2.contourArea(c) x1, y1, w1, h1 = cv2.boundingRect(c) if area > 1250: count_red = count_red + 1 cv2.rectangle(res_red, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 255), 2) if count_blue > 0 or count_red > 0: is_warning = True #cv2.imshow("crop_hsv",crop_hsv) #cv2.imshow("res",res) #cv2.imshow("res_blue",res_blue) #cv2.imshow("res_red",res_red) return is_warning
def candidate_process(img, densitys, rects, fg_mask): global bias scann_width = 5 rows, cols = img.shape min_val = img.min() new_rects = list() for idx, rect in enumerate(rects): print('\rcandidate: {}/{}'.format(idx, len(rects)), end='') x, y, w, h = rect if w > h: x0 = max(0, x - w // 2) y0 = max(0, y - w // 2) x1 = min(cols, x0 + w * 2) y1 = min(rows, y0 + w * 2) else: x0 = max(0, x - h // 2) y0 = max(0, y - h // 2) x1 = min(cols, x0 + h * 2) y1 = min(rows, y0 + h * 2) ''' x0 = max(0, x-w) y0 = max(0, y-h) x1 = min(cols, x0+w*3) y1 = min(rows, y0+h*3) ''' sub_img = img[y0:y1, x0:x1] sub_fg_mask = fg_mask[y0:y1, x0:x1] res = np.zeros(sub_img.shape, dtype=np.uint8) average = _calculate_average(sub_img, min_val, modality='mode') average -= bias averages = np.ones(sub_img.shape) * average density = int(np.median(densitys[y0:y1, x0:x1])) avg_densitys = np.ones(sub_img.shape) * density sub_lines_h, sub_lines_v, _, _ = find_lines(sub_img, averages, avg_densitys, scann_width=scann_width, printf=False, save_edge=True) scann_line_h = np.zeros(sub_img.shape, dtype=np.uint8) scann_line_v = scann_line_h.copy() for s, e, i in sub_lines_h: #if (e-s)*0.02 < 0.3: # filter out scann line that less than 0.3m # continue if (e - s) > 0.8 * (x1 - x0): continue scann_line_h[i, s:e + scann_width] = 255 for s, e, i in sub_lines_v: #if (e-s)*0.02 < 0.1: # filter out scann line that less than 0.3m # continue if (e - s) > 0.8 * (y1 - y0): continue scann_line_v[s:e + scann_width, i] = 255 scann_line_h = cv2.cvtColor(scann_line_h, cv2.COLOR_GRAY2BGR) gray = cv2.cvtColor(scann_line_h, cv2.COLOR_BGR2GRAY) #cv2.imwrite("56_scann_lines.png", bi_img) ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 5)) vertical = cv2.erode(binary, verticalStructure) vertical = cv2.dilate(vertical, verticalStructure) # close holes to make it solid rectangle kernel = np.ones((5, 5), np.uint8) close_h = cv2.morphologyEx(vertical, cv2.MORPH_CLOSE, kernel) scann_line_v = cv2.cvtColor(scann_line_v, cv2.COLOR_GRAY2BGR) gray_v = cv2.cvtColor(scann_line_v, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray_v, 0, 255, cv2.THRESH_BINARY) hStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 1)) tmp = cv2.erode(binary, hStructure) tmp = cv2.dilate(tmp, hStructure) # close holes to make it solid rectangle kernel = np.ones((5, 5), np.uint8) close_v = cv2.morphologyEx(tmp, cv2.MORPH_CLOSE, kernel) close = cv2.bitwise_and(close_v, close_h) close = cv2.bitwise_and(close, sub_fg_mask) _, contours, hierarchy = cv2.findContours(close, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) for c in contours: #x, y, w, h = cv2.boundingRect(c) xn, yn, wn, hn = cv2.boundingRect(c) xn += x0 yn += y0 + density - 1 new_rects.append(np.array([[xn, yn, xn + wn, yn + hn]])) return np.concatenate(new_rects, axis=0) if len(new_rects) > 0 else None
break found.append((x, y)) return found img = cv.imread('Lab8/s1.png') hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) lower_blue = np.array([0, 60, 180]) upper_blue = np.array([20, 140, 255]) mask = cv.inRange(hsv, lower_blue, upper_blue) mask2 = cv.morphologyEx(mask, cv.MORPH_OPEN, cv.getStructuringElement(cv.MORPH_ELLIPSE, (4, 4)), iterations=2) mask2 = cv.morphologyEx(mask2, cv.MORPH_DILATE, cv.getStructuringElement(cv.MORPH_ELLIPSE, (8, 8)), iterations=3) cv.imwrite("Lab8/mask.png", mask2) img2 = img.copy() for i in range(3): img2[:, :, i] *= mask2 cv.imwrite("Lab8/s2.png", img2) img2_g = cv.cvtColor(img2, cv.COLOR_BGR2GRAY) aug = iaa.pillike.EnhanceSharpness(factor=2.0) img3 = aug.augment_image(img2)
def MeanShift(frame, frame_hist, q_max, ix, iy, w, h, erode_1, erode_2): """ MeanShift 算法实现,核心函数 :param frame: 输入的一帧图片,这帧图片已经被转化为HSV图片 :param frame_hist: 对应的目标区域的统计直方图 :param q_max: 目标区域中统计直方图中的最大值 :param ix: 当前目标的位置,左上角点x坐标 :param iy: 当前目标的位置,右上角点y坐标 :param w: 目标的宽度,相对x坐标 :param h: 目标的高度,相对y坐标 :param erode_1: 腐蚀算子大小的选择 :param erode_2: 腐蚀算子大小的选择 :return: """ # 转HSV,并取H通道 frame_H = FC.HSV_frame_H_Cal(frame) # 计算反投影图,并做腐蚀膨胀并阈值化 back_projection_img = FC.Back_projection_cal(frame_H, frame_hist, q_max) back_projection_img = cv2.threshold(back_projection_img, 230, 255, cv2.THRESH_BINARY)[1] back_projection_img = cv2.erode(back_projection_img, cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (erode_1, erode_2)), iterations=2) #腐蚀 back_projection_img = cv2.dilate(back_projection_img, cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (8, 8)), iterations=2) #膨胀 # 保留之前算出的中心位置 xc_ = int(ix + w // 2) yc_ = int(iy + h // 2) w_ = w h_ = h # 迭代寻找最优中心点 for j in range(ITERATION_TIMES): while (True): try: xc, yc, S = FC.Centroid_Mass_Cal(back_projection_img, ix, iy, w, h) # 计算出当前目标的中心位置,面积 if xc > 0 and yc > 0: # 一个防错策略,防止因目标移速过快,跳出了初始搜索框,因此判断是否在初始搜索框找到目标,如果没有就扩大搜索框 break else: # 扩大搜索框 ix = ix - 10 w = w + 40 h = h + 40 except: # 另一个策略,如果当前无法找到目标,则保留原先的位置,等待下一轮进行搜索,这样可以减少中间丢失目标时程序出错跳出 xc = xc_ yc = yc_ w = w_ h = h_ break if np.sqrt( (ix + w / 2 - xc)**2 + (iy + h / 2 - yc)**2) < DISTANCE_THRESHOLD: # 判断找到合适的匹配位置,是就退出 break ix = int(xc - np.sqrt(S) // 2) # 更新左上角x坐标 iy = int(yc - np.sqrt(S) // 2) # 更新左上角y坐标 w = int(np.sqrt(S)) # 更新目标的宽度 h = int(np.sqrt(S)) # 更新目标的高度 return back_projection_img, ix, iy, w, h
def processing(path, geo_path, depth_path, density_path, info_path, save_path, nid): with open(path, 'rb') as f: img = pickle.load(f) #img = cv2.imread(depth_path, 0) #img = np.array(img) rows, columns = img.shape #depth_image = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) #depth_image = cv2.cvtColor(depth_image,cv2.COLOR_BGR2GRAY) with open(info_path, 'rb') as f: info = pickle.load(f) ref_plane = info['ref_plane'] buttom_edge = info['buttom_edge'] left_edge = info['left_edge'] horizontal, vertical = region_divide(nid, img, depth_path, ref_plane, save_path) geo_img_h = Image.open(geo_path) geo_img_v = geo_img_h.copy() density_image = cv2.imread(density_path, 0) bg = img.min() #img = signal.medfilt2d(img, (5,5)) global_avg = _calculate_average(img, bg, modality=config.modality_reference_average) averages, _ = reference_averages( img, density_image, horizontal, vertical, global_avg, bg, modality=config.modality_reference_average) blue_img = np.zeros((rows, columns, 3), dtype=np.uint8) blue_img[:, :, 0] = 255 red_img = np.zeros((rows, columns, 3), dtype=np.uint8) red_img[:, :, 2] = 255 reference_image = cv2.imread(depth_path, 1) reference_image_2 = reference_image.copy() tmp_averages = np.expand_dims(averages + bias, axis=2).repeat(3, axis=2) tmp_img = np.expand_dims(img, axis=2).repeat(3, axis=2) reference_image = np.where((tmp_img - tmp_averages) > bias, red_img, reference_image) reference_image = np.where( np.abs(tmp_img - tmp_averages) < bias, blue_img, reference_image) for c in vertical: cv2.line(reference_image, (c, 0), (c, rows), (255, 255, 255), 2, 4) for h in horizontal: cv2.line(reference_image, (0, h), (columns, h), (255, 255, 255), 2, 4) horizontal, vertical = refine_divide(reference_image, horizontal, vertical, nid, save_path) averages, avg_density = reference_averages( img, density_image, horizontal, vertical, global_avg, bg, modality=config.modality_reference_average) tmp_averages = np.expand_dims(averages + bias, axis=2).repeat(3, axis=2) tmp_img = np.expand_dims(img, axis=2).repeat(3, axis=2) reference_image_2 = np.where((tmp_img - tmp_averages) > bias, red_img, reference_image_2) reference_image_2 = np.where( np.abs(tmp_img - tmp_averages) < bias, blue_img, reference_image_2) for c in vertical: cv2.line(reference_image_2, (c, 0), (c, rows), (255, 255, 255), 2, 4) for h in horizontal: cv2.line(reference_image_2, (0, h), (columns, h), (255, 255, 255), 2, 4) scann_width = 5 sub_lines_h, sub_lines_v, bg_h, bg_v = find_lines(img, averages, avg_density, scann_width) im_cv_contour = cv2.imread(geo_path, 1) im_inner_rect_cand = im_cv_contour.copy() im_inner_rect_pred = im_cv_contour.copy() scann_line_img_h = np.zeros((rows, columns), dtype=np.uint8) scann_line_img_v = scann_line_img_h.copy() scann_line_bg = scann_line_img_h.copy() draw = ImageDraw.Draw(geo_img_h) draw_vertical = ImageDraw.Draw(geo_img_v) for s, e, h in sub_lines_h: #if (e-s)*0.02 < 0.3: # filter out scann line that less than 0.3m # continue if (e - s) * 0.02 > 6.0: bg_h.append([s, e, h]) continue scann_line_img_h[h, s:e + scann_width] = 255 draw.line((s, h) + (e + scann_width, h), fill=255) for s, e, w in sub_lines_v: #if (e-s)*0.02 < 0.1: # filter out scann line that less than 0.3m # continue if (e - s) * 0.02 > 6.0: bg_v.append([s, e, w]) continue scann_line_img_v[s:e + scann_width, w] = 255 draw_vertical.line((w, s) + (w, e + scann_width), fill=255) for s, e, h in bg_h: scann_line_bg[h, s:e + scann_width] = 255 for s, e, w in bg_v: scann_line_bg[s:e + scann_width, w] = 255 scann_line_img_h = cv2.cvtColor(scann_line_img_h, cv2.COLOR_GRAY2BGR) gray = cv2.cvtColor(scann_line_img_h, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 5)) vertical = cv2.erode(binary, verticalStructure) vertical = cv2.dilate(vertical, verticalStructure) # close holes to make it solid rectangle kernel = np.ones((5, 5), np.uint8) close_h = cv2.morphologyEx(vertical, cv2.MORPH_CLOSE, kernel) scann_line_img_v = cv2.cvtColor(scann_line_img_v, cv2.COLOR_GRAY2BGR) gray_v = cv2.cvtColor(scann_line_img_v, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray_v, 0, 255, cv2.THRESH_BINARY) hStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 1)) tmp = cv2.erode(binary, hStructure) tmp = cv2.dilate(tmp, hStructure) # close holes to make it solid rectangle kernel = np.ones((5, 5), np.uint8) close_v = cv2.morphologyEx(tmp, cv2.MORPH_CLOSE, kernel) scann_line_bg = cv2.cvtColor(scann_line_bg, cv2.COLOR_GRAY2BGR) gray = cv2.cvtColor(scann_line_bg, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) scann_line_bg = cv2.erode(binary, verticalStructure) scann_line_bg = cv2.dilate(scann_line_bg, verticalStructure) foreground_mask = 255 - scann_line_bg close = cv2.bitwise_and(close_v, close_h) close = cv2.bitwise_and(close, foreground_mask) _, contours, hierarchy = cv2.findContours(close, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) mask = np.ones((rows, columns, 3), dtype="uint8") idx = 0 candidates = list() rects = list() for c in contours: # compute the center of the contour M = cv2.moments(c) #x, y, w, h = cv2.boundingRect(c) x, y, w, h = cv2.boundingRect(c) # compensation of scann_height h = h + int(avg_density[y + h // 2, x + w // 2]) - 1 leftup = (x, y) rightdown = (x + w, y + h) #leftup, rightdown = order_points(c.reshape(c.shape[0], 2)) #w = rightdown[0] - leftup[0] #h = rightdown[1] - leftup[1] if (w < 12 or h <= 12) and (leftup[0] > rows - 100): # w<20, h<12 continue if (w < 20 or h <= 12) and (leftup[0] <= rows - 100): # w<20, h<12 continue #if w*h*0.02*0.02<0.1: # continue if w * 0.02 > 6.0 or h * 0.02 > 4.0: continue if w / h >= 5 or w / h < 0.2: continue #print(w, h) rects.append([x, y, w, h]) cX = int(M["m10"] / max(M["m00"], 0.0001)) cY = int(M["m01"] / max(M["m00"], 0.0001)) # draw the contour and center of the shape on the image cv2.drawContours(im_cv_contour, [c], -1, (255, 255, 255), 2) cv2.circle(im_cv_contour, (cX, cY), 3, (255, 255, 255), -1) candidates.append( np.array([[leftup[0], leftup[1], rightdown[0], rightdown[1]]])) cv2.rectangle(im_inner_rect_cand, leftup, rightdown, (0, 0, 255)) cv2.drawContours(mask, [c], -1, (255, 255, 255), 2) cv2.rectangle(mask, leftup, rightdown, (0, 0, 255)) cv2.circle(mask, (cX, cY), 3, (255, 255, 255), -1) cv2.putText(mask, "{}".format(idx), (cX - 10, cY - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) idx += 1 #cv2.imshow("Image", im_cv) #cv2.waitKey(0) if len(candidates) > 0: candidates = np.concatenate(candidates, axis=0) else: candidates = None labels = load_label(root, nid) if labels is not None: labels = utils.label_convert(labels, columns, rows) final_rects = candidate_process(img, avg_density, rects, foreground_mask) final_rects = utils.prediction_filter(final_rects, candidates) predictions = list() if final_rects is not None: for e in final_rects: x0, y0, x1, y1 = e leftup = (x0, y0) rightdown = (x1, y1) density = np.median(avg_density[y0:y1, x0:x1]) w = x1 - x0 h = y1 - y0 #leftup, rightdown = order_points(c.reshape(c.shape[0], 2)) #w = rightdown[0] - leftup[0] #h = rightdown[1] - leftup[1] if (w < 12 or h <= 12) and (leftup[0] > rows - 100): # w<20, h<12 continue if (w < 20 or h <= 12) and (leftup[0] <= rows - 100): # w<20, h<12 continue #if w*h*0.02*0.02<0.1: # continue if w * 0.02 > 5.0 or h * 0.02 > 4.0: continue if w / h >= 5 or w / h < 0.2: continue predictions.append( np.array([[leftup[0], leftup[1], rightdown[0], rightdown[1]]])) cv2.rectangle(im_inner_rect_pred, leftup, rightdown, (0, 255, 0)) if len(predictions) > 0: predictions = np.concatenate(predictions, axis=0) path_pred_txt = os.path.join(save_path, 'pred_txt') if not os.path.exists(path_pred_txt): os.makedirs(path_pred_txt) with open(os.path.join(path_pred_txt, '{}.txt'.format(nid)), 'w') as f: for i, e in enumerate(predictions): #f.write(str(cls_box_scores[i])+' '+ ' '.join(map(str, e))+'\n') f.write(' '.join(map(str, e)) + '\n') else: predictions = None #print(candidates[:, 0].max(), candidates[:, 1].max(),candidates[:, 2].max(), candidates[:, 3].max()) #print(labels[:, 0].max(), labels[:, 1].max(),labels[:, 2].max(), labels[:, 3].max()) tp, fp, fn = utils.confusion_matrix(predictions, labels) pred_height, actual_height = utils.height_error(predictions, labels) gdf = utils.window_line(predictions, img, averages, info_path, nid) path_window_geojson = os.path.join(save_path, 'window_geojson') if not os.path.exists(path_window_geojson): os.makedirs(path_window_geojson) path_window_ply = os.path.join(save_path, 'ply_detected_windows') if not os.path.exists(path_window_ply): os.makedirs(path_window_ply) #ply_path = '/Volumes/Qing Xiao/ikg/4_detection/part_dataset_v2/ply_in_depth/28_in_depth.ply' utils.window_line_cp(predictions, labels, averages + bias, info_path, path_window_ply, nid) if not gdf.empty: gdf.to_file(os.path.join(path_window_geojson, '{}.geojson'.format(nid)), driver='GeoJSON') #print("precision:", tp/(tp+fp)) #print('recall:', tp/(tp+fn)) path_image_tpfpfn = os.path.join(save_path, 'image_tpfpfn') if not os.path.exists(path_image_tpfpfn): os.makedirs(path_image_tpfpfn) draw_mis(geo_path, path_image_tpfpfn, predictions, labels, nid) path_scann_line_in_image_h = os.path.join(save_path, 'scann_line_in_image_h') if not os.path.exists(path_scann_line_in_image_h): os.makedirs(path_scann_line_in_image_h) path_refer_mask_refine = os.path.join(save_path, 'refer_mask_refine') if not os.path.exists(path_refer_mask_refine): os.makedirs(path_refer_mask_refine) path_scann_line_h = os.path.join(save_path, 'scann_line_h') if not os.path.exists(path_scann_line_h): os.makedirs(path_scann_line_h) path_fg_mask = os.path.join(save_path, 'fg_mask') if not os.path.exists(path_fg_mask): os.makedirs(path_fg_mask) path_scann_line_v = os.path.join(save_path, 'scann_line_v') if not os.path.exists(path_scann_line_v): os.makedirs(path_scann_line_v) path_scann_line_in_image_v = os.path.join(save_path, 'scann_line_in_image_v') if not os.path.exists(path_scann_line_in_image_v): os.makedirs(path_scann_line_in_image_v) path_morph = os.path.join(save_path, 'scann_line_morph') if not os.path.exists(path_morph): os.makedirs(path_morph) path_morph_h = os.path.join(save_path, 'scann_line_morph_h') if not os.path.exists(path_morph_h): os.makedirs(path_morph_h) path_morph_v = os.path.join(save_path, 'scann_line_morph_v') if not os.path.exists(path_morph_v): os.makedirs(path_morph_v) path_contours = os.path.join(save_path, 'contours') if not os.path.exists(path_contours): os.makedirs(path_contours) path_mask = os.path.join(save_path, 'mask') if not os.path.exists(path_mask): os.makedirs(path_mask) path_inner_rect_cand = os.path.join(save_path, 'inner_rect_cand') if not os.path.exists(path_inner_rect_cand): os.makedirs(path_inner_rect_cand) path_inner_rect_pred = os.path.join(save_path, 'inner_rect_pred') if not os.path.exists(path_inner_rect_pred): os.makedirs(path_inner_rect_pred) path_refer_mask = os.path.join(save_path, 'refer_mask') if not os.path.exists(path_refer_mask): os.makedirs(path_refer_mask) path_scann_line_dbscan = os.path.join(save_path, 'scann_line_dbscan') if not os.path.exists(path_scann_line_dbscan): os.makedirs(path_scann_line_dbscan) path_dbscan_rect = os.path.join(save_path, 'dbscan_rect') if not os.path.exists(path_dbscan_rect): os.makedirs(path_dbscan_rect) #cluster_img.save(os.path.join(path_scann_line_dbscan, '{}.png'.format(nid))) #cv2.imwrite(os.path.join(path_dbscan_rect, '{}.png'.format(nid)), im_outer_rect) cv2.imwrite(os.path.join(path_refer_mask_refine, '{}.png'.format(nid)), reference_image_2) cv2.imwrite(os.path.join(path_refer_mask, '{}.png'.format(nid)), reference_image) geo_img_h.save( os.path.join(path_scann_line_in_image_h, '{}.png'.format(nid))) geo_img_v.save( os.path.join(path_scann_line_in_image_v, '{}.png'.format(nid))) cv2.imwrite(os.path.join(path_scann_line_h, '{}.png'.format(nid)), scann_line_img_h) cv2.imwrite(os.path.join(path_fg_mask, '{}.png'.format(nid)), scann_line_bg) cv2.imwrite(os.path.join(path_morph, '{}.png'.format(nid)), close) cv2.imwrite(os.path.join(path_contours, '{}.png'.format(nid)), im_cv_contour) cv2.imwrite(os.path.join(path_inner_rect_cand, '{}.png'.format(nid)), im_inner_rect_cand) cv2.imwrite(os.path.join(path_inner_rect_pred, '{}.png'.format(nid)), im_inner_rect_pred) cv2.imwrite(os.path.join(path_mask, '{}.png'.format(nid)), mask) cv2.imwrite(os.path.join(path_scann_line_v, '{}.png'.format(nid)), scann_line_img_v) cv2.imwrite(os.path.join(path_morph_h, '{}.png'.format(nid)), close_h) cv2.imwrite(os.path.join(path_morph_v, '{}.png'.format(nid)), close_v) return tp, fp, fn, pred_height, actual_height, gdf
def dark_or_light_objects_only(self, color='dark'): if self.image_mask is None: fill_color = [1, 1, 1] if not self.params['circular_mask_x'] is None: self.image_mask = np.zeros_like(self.imgScaled) cv2.circle(self.image_mask, (self.params['circular_mask_x'], self.params['circular_mask_y']), int(self.params['circular_mask_r']), fill_color, -1) # TODO test! elif not self.params['roi_points'] is None: self.image_mask = np.zeros_like(self.imgScaled) hull = cv2.convexHull( np.array(self.params['roi_points'], dtype=np.int32)) cv2.fillConvexPoly(self.image_mask, hull, fill_color) # , -1) if not self.image_mask is None: self.imgScaled = self.image_mask * self.imgScaled if self.debug and self.pub_mask.get_num_connections() > 0: c = cv2.cvtColor(np.uint8(self.image_mask), cv2.COLOR_GRAY2BGR) img = self.cvbridge.cv2_to_imgmsg( c, 'bgr8') # might need to change to bgr for color cameras self.pub_mask.publish(img) # TODO do i want to return in both of these cases? might cause more discontinuity # than necessary # If we need to reset background image, grab one, and move on to the next frame if self.backgroundImage is None or self.reset_background_flag: reset_background(self) self.reset_background_flag = False return if self.add_image_to_background_flag: self.add_image_to_background(color) self.add_image_to_background_flag = False return # TODO TODO fix # TODO is this actually nonzero? warn if it's not? if self.params['backgroundupdate'] != 0: cv2.accumulateWeighted( np.float32(self.imgScaled), self.backgroundImage, self.params['backgroundupdate'] ) # this needs to be here, otherwise there's an accumulation of something in the background # break into functions? if self.params['medianbgupdateinterval'] != 0: t = rospy.Time.now().to_sec() # TODO TODO used? if not self.__dict__.has_key('medianbgimages'): self.medianbgimages = [self.imgScaled] self.medianbgimages_times = [t] if t - self.medianbgimages_times[-1] > self.params[ 'medianbgupdateinterval']: self.medianbgimages.append(self.imgScaled) self.medianbgimages_times.append(t) if len(self.medianbgimages) > 3: self.backgroundImage = copy.copy( np.float32(np.median(self.medianbgimages, axis=0))) self.medianbgimages.pop(0) self.medianbgimages_times.pop(0) rospy.loginfo('reset background with median image') # TODO put in init? try: kernel = self.kernel except AttributeError: kern_d = self.params['morph_open_kernel_size'] kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (kern_d, kern_d)) self.kernel = kernel if color == 'dark': self.threshed = cv2.compare(np.float32( self.imgScaled), self.backgroundImage - self.params['threshold'], cv2.CMP_LT) # CMP_LT is less than elif color == 'light': self.threshed = cv2.compare(np.float32( self.imgScaled), self.backgroundImage + self.params['threshold'], cv2.CMP_GT) # CMP_GT is greater than elif color == 'darkorlight': # TODO clean up #absdiff = cv2.absdiff(np.float32(self.imgScaled), self.backgroundImage) #retval, self.threshed = cv2.threshold(absdiff, self.params['threshold'], 255, 0) #self.threshed = np.uint8(self.threshed) dark = cv2.compare(np.float32(self.imgScaled), self.backgroundImage - self.params['threshold'], cv2.CMP_LT) # CMP_LT is less than light = cv2.compare(np.float32(self.imgScaled), self.backgroundImage + self.params['threshold'], cv2.CMP_GT) # CMP_GT is greater than self.threshed = dark + light convert_to_gray_if_necessary(self) if self.debug and self.pub_threshed.get_num_connections() > 0: c = cv2.cvtColor(np.uint8(self.threshed), cv2.COLOR_GRAY2BGR) img = self.cvbridge.cv2_to_imgmsg( c, 'bgr8') # might need to change to bgr for color cameras self.pub_threshed.publish(img) # noise removal if self.params['denoise']: self.threshed = cv2.morphologyEx(self.threshed, cv2.MORPH_OPEN, kernel, iterations=1) if self.debug and self.pub_denoised.get_num_connections() > 0: c = cv2.cvtColor(np.uint8(self.threshed), cv2.COLOR_GRAY2BGR) img = self.cvbridge.cv2_to_imgmsg( c, 'bgr8') # might need to change to bgr for color cameras self.pub_denoised.publish(img) erode_and_dialate(self) coords_and_area = extract_and_publish_contours(self) # publish the processed image # for troubleshooting image processing pipeline if self.debug and self.pub_processed.get_num_connections() > 0: cimg = cv2.cvtColor(np.uint8(self.threshed), cv2.COLOR_GRAY2BGR) for x, y, area in coords_and_area: cv2.putText(cimg, str(area), (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, \ (255, 255, 255), 1, cv2.LINE_AA) # TODO test whether this works in OpenCV 2 and 3 (i think it works in 3 for me, despite # Floris's comment img = self.cvbridge.cv2_to_imgmsg( cimg, 'bgr8') # might need to change to bgr for color cameras self.pub_processed.publish(img) reset_background_if_difference_is_very_large(self, color)
[[_margin, _height + _margin]], [[_width + _margin, _height + _margin]], [[_width + _margin, _margin]], ]) pts_dst = np.array(corners, np.float32) img = cv2.imread('tag3.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.bilateralFilter(gray, 1, 10, 120) edges = cv2.Canny(gray, 10, CANNY) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (MORPH, MORPH)) kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (MORPH2, MORPH2)) closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) #dilation = cv2.dilate(closed,kernel) #opening = cv2.morphologyEx(dilation, cv2.MORPH_OPEN, kernel2) __, contours, h = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cont in contours: if cv2.contourArea(cont) > 5000:
def extract_cords(imgPath): cords_array = [] # Read the image img = cv2.imread(imgPath, 0) # Thresholding the image (thresh, img_bin) = cv2.threshold(img, 128, 255,cv2.THRESH_BINARY| cv2.THRESH_OTSU) # Invert the image img_bin = 255-img_bin cv2.imwrite("Image_bin.jpg",img_bin) # Defining a kernel length kernel_length = np.array(img).shape[1]//80 # A verticle kernel of (1 X kernel_length), which will detect all the verticle lines from the image. verticle_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kernel_length)) # A horizontal kernel of (kernel_length X 1), which will help to detect all the horizontal line from the image. hori_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_length, 1)) # A kernel of (3 X 3) ones. kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # Morphological operation to detect vertical lines from an image img_temp1 = cv2.erode(img_bin, verticle_kernel, iterations=3) verticle_lines_img = cv2.dilate(img_temp1, verticle_kernel, iterations=3) # cv2.imwrite("verticle_lines.jpg",verticle_lines_img) # Morphological operation to detect horizontal lines from an image img_temp2 = cv2.erode(img_bin, hori_kernel, iterations=3) horizontal_lines_img = cv2.dilate(img_temp2, hori_kernel, iterations=3) # cv2.imwrite("horizontal_lines.jpg",horizontal_lines_img) # Weighting parameters, this will decide the quantity of an image to be added to make a new image. alpha = 0.5 beta = 1.0 - alpha # This function helps to add two image with specific weight parameter to get a third image as summation of two image. img_final_bin = cv2.addWeighted(verticle_lines_img, alpha, horizontal_lines_img, beta, 0.0) img_final_bin = cv2.erode(~img_final_bin, kernel, iterations=2) (thresh, img_final_bin) = cv2.threshold(img_final_bin, 128,255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # cv2.imwrite("img_final_bin.jpg",img_final_bin) # Find contours for image, which will detect all the boxes im2, contours, hierarchy = cv2.findContours(img_final_bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Sort all the contours by top to bottom. (contours, boundingBoxes) = sort_contours(contours, method="top-to-bottom") idx = 0 for c in contours: # Returns the location and width,height for every contour x, y, w, h = cv2.boundingRect(c) # print(x, y, w, h) if (w > 1000 and h > 800): idx += 1 # HardCoding for testing, will remove later cords_array.append(((y+150)/5, (x-70)/7, (y+h)/7, (x+w+100)/7)) # new_img = img[y:y+h, x:x+w] # print(new_img) # cv2.imwrite(os.path.join("cropped/",str(idx)) + '.png', new_img) # PILimage = Image.fromarray(new_img) # PILimage.save(os.path.join("cropped/",str(idx)) + '.png', dpi=(200,200)) # # If the box height is greater then 20, widht is >80, then only save it as a box in "cropped/" folder. if (w > 800 and h > 500) and w>3*h: idx += 1 new_img = img[y:y+h, x:x+w] # cv2.imwrite(os.path.join("cropped/",str(idx)) + '.png', new_img) PILimage = Image.fromarray(new_img) PILimage.save(os.path.join("cropped/",str(idx)) + '.png', dpi=(200,200)) return cords_array
def reduzir_ruidos(foregroundMask): morf = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) return cv2.morphologyEx(numpy.float32(foregroundMask), cv2.MORPH_OPEN, morf)
def main(): global new_image rs_img = rs_process() rospy.init_node('hand_tracking', anonymous=True) rospy.loginfo("Hand Detection Start!") #Marker Publisher Initialize pub = rospy.Publisher('/hand_marker', Marker, queue_size=1) hand_mark = MarkerGenerator() hand_mark.type = Marker.SPHERE_LIST hand_mark.scale = [.07] * 3 hand_mark.frame_id = "/camera_color_optical_frame" hand_mark.id = 0 hand_mark.lifetime = 10000 #hand detect args parser = argparse.ArgumentParser() parser.add_argument('-sth', '--scorethreshold', dest='score_thresh', type=float, default=0.5, help='Score threshold for displaying bounding boxes') parser.add_argument('-fps', '--fps', dest='fps', type=int, default=1, help='Show FPS on detection/display visualization') parser.add_argument('-src', '--source', dest='video_source', default=0, help='Device index of the camera.') parser.add_argument('-wd', '--width', dest='width', type=int, default=640, help='Width of the frames in the video stream.') parser.add_argument('-ht', '--height', dest='height', type=int, default=360, help='Height of the frames in the video stream.') parser.add_argument( '-ds', '--display', dest='display', type=int, default=0, help='Display the detected images using OpenCV. This reduces FPS') parser.add_argument('-num-w', '--num-workers', dest='num_workers', type=int, default=4, help='Number of workers.') parser.add_argument('-q-size', '--queue-size', dest='queue_size', type=int, default=5, help='Size of the queue.') args = parser.parse_args() num_hands_detect = 2 im_width, im_height = (args.width, args.height) #time for fps calculation start_time = datetime.datetime.now() num_frames = 0 #skin filter color lower = np.array([0, 48, 80], dtype="uint8") upper = np.array([20, 255, 255], dtype="uint8") ####################################### #Define the frame to transform ####################################### target_frame = "/camera_color_optical_frame" ######FROM reference_frame = "/base_link" ####TO ##################################### #Define the numpy array to record the consequences of the hand location ###################################### # hand_pos = np.empty((1,3)) is_transform_target = False if (is_transform_target): listener = tf.TransformListener() listener.waitForTransform(reference_frame, target_frame, rospy.Time(0), rospy.Duration(4.0)) hand_mark.frame_id = reference_frame else: hand_mark.frame_id = target_frame hand_pose_list = [] while not rospy.is_shutdown(): #get rgb,depth frames for synchronized frames if not new_image: continue im_rgb = rs_image_rgb # im_rgb = cv2.cvtColor(rs_image_rgb, cv2.COLOR_BGR2RGB) im_depth = rs_image_depth new_image = False #add check # depth_map = np.array(rs_image_depth, dtype=np.uint8) depth_map = cv2.applyColorMap( cv2.convertScaleAbs(rs_image_depth, alpha=0.03), cv2.COLORMAP_JET) # cv2.imshow("Depth Image", depth_map) cv2.imshow("rs_image_rgb", rs_image_rgb) try: image_np = im_rgb except: print("Error converting to RGB") # actual hand detection boxes, scores = detector_utils.detect_objects(image_np, detection_graph, sess) # draw bounding boxes detector_utils.draw_box_on_image(num_hands_detect, args.score_thresh, scores, boxes, im_width, im_height, image_np) if (scores[0] > args.score_thresh): (left, right, top, bottom) = (boxes[0][1] * im_width, boxes[0][3] * im_width, boxes[0][0] * im_height, boxes[0][2] * im_height) p1 = (int(left), int(top)) p2 = (int(right), int(bottom)) # print p1,p2,int(left),int(top),int(right),int(bottom) image_hand = image_np[int(top):int(bottom), int(left):int(right)] # cv2.namedWindow("hand", cv2.WINDOW_NORMAL) cv2.imshow('hand', cv2.cvtColor(image_hand, cv2.COLOR_RGB2BGR)) align_hand = im_rgb[int(top):int(bottom), int(left):int(right)] align_depth = depth_map[int(top):int(bottom), int(left):int(right)] align_hand_detect = np.hstack((align_hand, align_depth)) # cv2.namedWindow('align hand', cv2.WINDOW_AUTOSIZE) # cv2.imshow('align hand', align_hand_detect) # cv2.imshow('align_hand_bgr', align_hand) align_hand = cv2.cvtColor(align_hand, cv2.COLOR_BGR2RGB) #skin filtering converted = cv2.cvtColor(align_hand, cv2.COLOR_BGR2HSV) skinMask = cv2.inRange(converted, lower, upper) # cv2.imshow("skinMask", skinMask) # apply a series of erosions and dilations to the mask # using an elliptical kernel # kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)) # skinMask = cv2.erode(skinMask, kernel, iterations = 2) # skinMask = cv2.dilate(skinMask, kernel, iterations = 2) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)) skinMask = cv2.erode(skinMask, kernel, iterations=3) skinMask = cv2.dilate(skinMask, kernel, iterations=3) # blur the mask to help remove noise, then apply the # mask to the frame skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0) skin = cv2.bitwise_and(align_hand, align_hand, mask=skinMask) # show the skin in the image along with the mask # cv2.imshow("images", np.hstack([align_hand, skin])) #end skin depth_pixel = [(int(left) + int(right)) / 2, (int(top) + int(bottom)) / 2] # depth_point = [0.0,0.0,0.0] depth_point = rs.rs2_deproject_pixel_to_point( depth_intrin, depth_pixel, im_depth[depth_pixel[1], depth_pixel[0]] * depth_scale) print depth_point hand_mark.counter = 0 t = rospy.get_time() hand_mark.color = [0, 1, 0, 1] # hand_mark.id = hand_mark.id + 1 # if (hand_mark.id > 100000) : # hand_mark.id = 0 # ## hand in /camera_color_optical_frame # print ('id ',hand_mark.id) m0 = hand_mark.marker(points=[(depth_point[0], depth_point[1], depth_point[2])]) hand_point_x = depth_point[0] hand_point_y = depth_point[1] hand_point_z = depth_point[2] if (is_transform_target): ######################################################################### ##convert /camera_color_optical_frame => /world ######################################################################### #transform position from target_frame to reference frame target_ref_camera = PointStamped() target_ref_camera.header.frame_id = target_frame target_ref_camera.header.stamp = rospy.Time(0) target_ref_camera.point = m.points[0] p = listener.transformPoint(reference_frame, target_ref_camera) # p=listener.transformPoint(reference_frame,hand_mark) m = hand_mark.marker(points=[(p.point.x, p.point.y, p.point.z)]) #substitute data for the variable hand_point_x = p.point.x hand_point_y = p.point.y hand_point_z = p.point.z # pub.publish(m) #offset z-axiz # hand_mark.id = 1 # m = hand_mark.marker(points= [(p.point.x, p.point.y, p.point.z + 0.10)]) # pub.publish(m) else: # print('published!') ####append the data if 0.15 <= hand_point_z <= 0.75 and -0.4 <= hand_point_x <= 0.4: print("recorded hand point") hand_pose = [ hand_point_x, hand_point_y, hand_point_z, 0.0, 0.0, 0.0, 1.0 ] print hand_pose hand_pose_list.append(hand_pose) pub.publish(m0) #substitute data for the variable hand_point_x = depth_point[0] hand_point_y = depth_point[1] - 0.08 hand_point_z = depth_point[2] #### offset z-axiz # hand_mark.id = 1 m1 = hand_mark.marker(points=[(depth_point[0], depth_point[1] - 0.08, depth_point[2])]) # m = hand_mark.marker(points= [(p.point.x, p.point.y, p.point.z + 0.10)]) # pub.publish(m1) # Calculate Frames per second (FPS) num_frames += 1 elapsed_time = (datetime.datetime.now() - start_time).total_seconds() fps = num_frames / elapsed_time #display window if (args.display > 0): # Display FPS on frame if (args.fps > 0): detector_utils.draw_fps_on_image("FPS : " + str(float(fps)), image_np) cv2.imshow('Single Threaded Detection', cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)) else: print("frames processed: ", num_frames, "elapsed time: ", elapsed_time, "fps: ", str(int(fps))) if cv2.waitKey(10) & 0xFF == ord('q'): cv2.destroyAllWindows() break print('save hand_pub.npy') # np.save('./hand_pub.npy',hand_pos) np.save("hand_pub", hand_pose_list)
method="left-to-right")[0] #排序,从左到右,从上到下 # print(refCnts) digits = {} # 遍历每一个轮廓 for (i, c) in enumerate(refCnts): # 计算外接矩形并且resize成合适大小 (x, y, w, h) = cv2.boundingRect(c) roi = ref[y:y + h, x:x + w] roi = cv2.resize(roi, (57, 88)) # 每一个数字对应每一个模板 digits[i] = roi # 初始化卷积核 rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3)) sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) #读取输入图像,预处理 image = cv2.imread(args["image"]) cv_show('image', image) image = myutils.resize(image, width=300) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) cv_show('gray', gray) #礼帽操作,突出更明亮的区域 tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) cv_show('tophat', tophat) # gradX = cv2.Sobel( tophat,
img1 = cv2.imread('imagens/moeda.png') img2 = cv2.imread('imagens/esqueleto.tif') fig = plt.figure(figsize=(15, 15)) ax1 = fig.add_subplot(221) plt.imshow(img1) plt.title("Imagem Original") ax2 = fig.add_subplot(222) plt.imshow(img2) plt.title("Imagem Original") plt.show() elem_str1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) elem_str2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (21, 21)) print(elem_str1) print(elem_str2) imgProc1 = cv2.morphologyEx(img1, cv2.MORPH_GRADIENT, elem_str1) imgProc2 = cv2.morphologyEx(img2, cv2.MORPH_TOPHAT, elem_str2) imgProc3 = cv2.morphologyEx(img2, cv2.MORPH_BLACKHAT, elem_str2) fig = plt.figure(figsize=(15, 15)) ax1 = fig.add_subplot(131) plt.imshow(imgProc1) plt.title("Gradiete Morfologico")
return deedgedImg # Remove little block # thresh = diff thresh = deEdge(diff, xthresh=0.2, ythresh=0.2) cv.imshow("3", thresh) # Gauss filtering size = int(height * 0.005) + (int(height * 0.005) - 1) % 2 print("SIZE :", size) blur = cv.GaussianBlur(thresh, (size, size), 0) cv.imshow("3.5", blur) # Morphology operation kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) thresh = cv.morphologyEx(blur, cv.MORPH_CLOSE, kernel, iterations=15) cv.imshow("3.9", thresh) # Gauss filtering size = int(height * 0.014) + (int(height * 0.014) - 1) % 2 print("SIZE :", size) blur = cv.GaussianBlur(thresh, (3, 3), 0) blur = thresh cv.imshow("4", blur) # Threshold filtering value, thresh = cv.threshold(blur, 10, 255, cv.THRESH_OTSU | cv.THRESH_TOZERO) print(value) cv.imshow("5", thresh)
def image_to_speed(view1, view2, state): """This is the function where you should write your code to control your car. You need to calculate your car wheels' speed based on the views. Whenever you need to print something, use log.append(). Args: view1 (ndarray): The left-bottom view, it is grayscale, 1 * 120 * 160 view2 (ndarray): The right-bottom view, it is colorful, 3 * 120 * 160 state: your car's state, initially None, you can use it by state.set(value) and state.get(). It will persist during continuous calls of image_to_speed. It will not be reset to None once you have set it. Returns: (left, right): your car wheels' speed """ if state.get() is None: state.set(0) ''' else: state.set(state.get()+1)''' log.append("#" + str(state.get())) cv2.imwrite("stoplne8.jpg", view1) #red light detect red_flag = 0 im3 = view2.copy() im3[:, 0:300] = 0 #cv2.imshow("im",im3) gray = cv2.cvtColor(im3, cv2.COLOR_BGR2GRAY) hsv = cv2.cvtColor(im3, cv2.COLOR_BGR2HSV) H, S, V = cv2.split(hsv) label = (H > 170) * (H < 185) * (S > 170) * (V > 190) thresh = gray * label thresh[label] = 255 #cv2.imshow("thresh",thresh) element = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) dilated = cv2.dilate(thresh, element) ret, thresh = cv2.threshold(dilated, 127, 255, cv2.THRESH_BINARY) #cv2.imshow("thresh2",thresh) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) rect_max = [] area = 0 for i in range(0, len(contours)): contour_area = cv2.contourArea(contours[i]) if contour_area > area: area = contour_area rect = cv2.boundingRect(contours[i]) w = rect[2] h = rect[3] aspect_ratio = max(w, h) / (min(w, h) * 1.0) if w > 10 and h > 10 and aspect_ratio < 1.5: rect_max.clear() rect_max.append( [rect[0], rect[1], rect[0] + rect[2], rect[1] + rect[3]]) if len(rect_max) != 0: red_flag = 1 log.append("red_flag= " + str(red_flag)) #stop_flag stop_flag = 0 im4 = view1.copy() gray = cv2.cvtColor(im4, cv2.COLOR_BGR2GRAY) im4_hsv = cv2.cvtColor(im4, cv2.COLOR_BGR2HSV) H, S, V = cv2.split(im4_hsv) label = (H > 90) * (H < 140) * (S < 10) * (V > 150) thresh = gray * label thresh[label] = 255 #cv2.imshow("im",im4) #cv2.imshow("thresh",thresh) _, maxVal, _, _ = cv2.minMaxLoc(thresh[60:90, 70:90]) if maxVal == 255: stop_flag = 1 log.append("stop") sign_flag = 0 if view2 is not None: sign_classes = { 14: 'Stop', 33: 'Turn right', 34: 'Turn left', 35: 'Straight' } svm = SVM() detector = detection() im = view2 rect = detector.ensemble(im) if rect: xmin, ymin, xmax, ymax = rect roi = im[ymin:ymax, xmin:xmax, :] id_num = svm.predict(roi, "hog") sign_flag = 1 log.append("id:" + str(id_num)) log.append(sign_classes[id_num]) log.append(str(view1.shape)) # image is left-bottom view, shaped as 160*120 #view1 = view1.astype(int) hsv = cv2.cvtColor(view1, cv2.COLOR_BGR2HSV) H, S, V = cv2.split(hsv) #cv2.imshow("s",S) ret, thresh = cv2.threshold(S, 70, 255, cv2.THRESH_BINARY) #cv2.imshow("thresh",thresh) drawpic = im leftedge = [] leftLossNum = 0 leftpoint = [] rowst = 40 rowed = 60 distance = 45 for row in range(rowst, rowed): leftpt = -1 for col in range(0, 160): if thresh[row][col] == 255: #drawpic = cv2.circle(drawpic, (col,row), 1, (255, 0, 0)) if row == rowst or row == (rowed - 1): leftpoint.append((col, row)) #drawpic = cv2.circle(drawpic, (col, row), 1, (0, 0, 255)) leftpt = col leftedge.append(leftpt) break if leftpt == -1: leftpt = 0 leftLossNum += 1 if len(leftpoint) == 2: x1 = leftpoint[0][0] y1 = leftpoint[0][1] x2 = leftpoint[1][0] y2 = leftpoint[1][1] middle_x = (x1 + x2) / 2 print("middle_x: " + str(middle_x)) if x1 != x2: k1 = (y1 - y2) / (x1 - x2) delta_x = pow(pow(distance, 2) / (1 + 1 / pow(k1, 2)), 0.5) x0 = middle_x + delta_x else: delta_x = distance x0 = middle_x + delta_x x0 = min(x0, 159) log.append("x0: " + str(x0)) elif len(leftedge) > 1: x0 = np.mean(leftedge) + distance x0 = min(x0, 159) log.append("x0: " + str(x0)) else: x0 = 115 log.append("x0: " + str(x0)) log.append(str(len(leftedge))) log.append("leftLossNum: " + str(leftLossNum)) if sign_flag == 1: if id_num == 33: x0 = 115 log.append("x0: " + str(x0)) if id_num == 34: state.set(state.get() + 1) sign_flag = 1 id_num = 35 if sign_flag == 0 and state.get() > 0 and state.get() < 10: #state.set(0) state.set(state.get() + 100) x0 = 40 elif sign_flag == 0 and state.get() >= 100: x0 = 40 state.set(state.get() + 100) if state.get() >= 100 * 8: state.set(0) error = (x0 - 80.0) / 80.0 log.append("error: " + str(error)) speed = 0.5 if abs(error) > 0.2: Kp = 1.3 else: Kp = 1.0 SENSE = 1.0 left_speed = speed + Kp * error * SENSE right_speed = speed - Kp * error * SENSE if sign_flag == 1: if id_num == 35: right_speed = 1.0 left_speed = 1.0 if (stop_flag == 1 and red_flag == 1): left_speed = 0 right_speed = 0 #if left_speed>0 and right_speed>0: return left_speed, right_speed
width, height, _ = image.shape # resize image resize = cv2.resize(image, (3900, 1550)) # preprocess image gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY) retval, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY) # Perform morphological operations based on image dimensions if width > 3900: # morphologically close all small details in the cards to avoid false contours later # then dilate the image to segment out individual players morphed = cv2.morphologyEx( thresh, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))) morphed = cv2.dilate(morphed, cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)), iterations=8) else: # morphologically close all small details in the cards to avoid false contours later morphed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, None, iterations=12) # sharpen the image if it is smaller image if width < 3900: resize = cv2.filter2D(resize, -1, k) # find contours, use CCOMP for smaller image and EXTERNAL for larger image if width > 3900: _, cnts, hier = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
def getBoxes(y_pred, detection_threshold=0.7, text_threshold=0.4, link_threshold=0.4, size_threshold=10): box_groups = [] for y_pred_cur in y_pred: # Prepare data textmap = y_pred_cur[..., 0].copy() linkmap = y_pred_cur[..., 1].copy() img_h, img_w = textmap.shape _, text_score = cv2.threshold(textmap, thresh=text_threshold, maxval=1, type=cv2.THRESH_BINARY) _, link_score = cv2.threshold(linkmap, thresh=link_threshold, maxval=1, type=cv2.THRESH_BINARY) n_components, labels, stats, _ = cv2.connectedComponentsWithStats(np.clip( text_score + link_score, 0, 1).astype('uint8'), connectivity=4) boxes = [] for component_id in range(1, n_components): # Filter by size size = stats[component_id, cv2.CC_STAT_AREA] if size < size_threshold: continue # If the maximum value within this connected component is less than # text threshold, we skip it. if np.max(textmap[labels == component_id]) < detection_threshold: continue # Make segmentation map. It is 255 where we find text, 0 otherwise. segmap = np.zeros_like(textmap) segmap[labels == component_id] = 255 segmap[np.logical_and(link_score, text_score)] = 0 x, y, w, h = [ stats[component_id, key] for key in [cv2.CC_STAT_LEFT, cv2.CC_STAT_TOP, cv2.CC_STAT_WIDTH, cv2.CC_STAT_HEIGHT] ] # Expand the elements of the segmentation map niter = int(np.sqrt(size * min(w, h) / (w * h)) * 2) sx, sy = max(x - niter, 0), max(y - niter, 0) ex, ey = min(x + w + niter + 1, img_w), min(y + h + niter + 1, img_h) segmap[sy:ey, sx:ex] = cv2.dilate( segmap[sy:ey, sx:ex], cv2.getStructuringElement(cv2.MORPH_RECT, (1 + niter, 1 + niter))) # Make rotated box from contour contours = cv2.findContours(segmap.astype('uint8'), mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)[-2] contour = contours[0] box = cv2.boxPoints(cv2.minAreaRect(contour)) # Check to see if we have a diamond w, h = np.linalg.norm(box[0] - box[1]), np.linalg.norm(box[1] - box[2]) box_ratio = max(w, h) / (min(w, h) + 1e-5) if abs(1 - box_ratio) <= 0.1: l, r = contour[:, 0, 0].min(), contour[:, 0, 0].max() t, b = contour[:, 0, 1].min(), contour[:, 0, 1].max() box = np.array([[l, t], [r, t], [r, b], [l, b]], dtype=np.float32) else: # Make clock-wise order box = np.array(np.roll(box, 4 - box.sum(axis=1).argmin(), 0)) boxes.append(2 * box) box_groups.append(np.array(boxes)) return box_groups
def filter_image(frame): blurred = cv2.GaussianBlur(frame,(9,9),0) hsv= cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV) lower_orange=np.array([0,170,0]) upper_orange=np.array([15,255,255]) mask = cv2.inRange(hsv,lower_orange,upper_orange) lower_white = np.array([0, 0, 210]) upper_white = np.array([255, 210, 255]) white_mask = cv2.inRange(hsv, lower_white, upper_white) white_edges = cv2.Canny(white_mask, 10, 30, 3) hsvMask = mask.copy() # white_points = cv2.findNonZero(mask) # edges = cv2.Canny(mask, 100, 200, 3) # contours,hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) rectangle_list = [] rectangle_map = {} # for cnt in contours: # x,y,w,h = cv2.boundingRect(cnt) # cv2.rectangle(res,(x,y),(x+w,y+h),(0,0,0),-1) # mask = cv2.cvtColor(res, cv2.COLOR_RGB2GRAY) # res[mask = 255] = [0, 255, 0] structuringElement = cv2.getStructuringElement(cv2.MORPH_RECT, (70, 70)) structuringElement2 = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 50)) lineElement = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 90)) mask = cv2.morphologyEx( mask, cv2.MORPH_CLOSE, lineElement) white_edges = cv2.bitwise_and(white_edges, white_edges, mask=~mask) laneLines= cv2.HoughLinesP(white_edges, rho=1, theta=np.pi/360, threshold=100, minLineLength=60, maxLineGap=25) # lines = cv2.HoughLinesP(mask, rho=1, theta=np.pi / 180, threshold=100, minLineLength=150, maxLineGap=100) # mask = cv2.morphologyEx( mask, cv2.MORPH_CLOSE, structuringElement ) res = cv2.bitwise_and(frame, frame, mask=~mask) if laneLines is not None: for l in laneLines[0]: cv2.line(mask, (l[0], l[1]), (l[2], l[3]), (255, 255, 255), 4) # NEARBY_RANGE = 100 # LENGTH = len(contours) # status = np.zeros((LENGTH,1)) # for i,cnt1 in enumerate(contours): # x = i # if i != LENGTH-1: # for j,cnt2 in enumerate(contours[i+1:]): # x = x+1 # dist = find_if_close(cnt1,cnt2) # if dist == True: # val = min(status[i],status[x]) # status[x] = status[i] = val # else: # if status[x]==status[i]: # status[x] = i+1 # unified = [] # maximum = int(status.max())+1 # for i in xrange(maximum): # pos = np.where(status==i)[0] # if pos.size != 0: # cont = np.vstack(contours[i] for i in pos) # hull = cv2.convexHull(cont) # unified.append(hull) # cv2.drawContours(img,unified,-1,(0,255,0),2) # cv2.drawContours(thresh,unified,-1,255,-1) # for key, val in rectangle_map: # if (abs((x + w) - (key[0] + key[2])) < NEARBY_RANGE and abs((y+h) - (key[1] + key[3])) < NEARBY_RANGE): # smallest_x = x if x < key[0] else key[0] # smallest_y = y if y < key[1] else key[1] # largest_x = (x + w) if (x + w) > (key[0] + key[2]) else (key[0] + key[2]) # largest_y = (y + h) if (y + h) > (key[1] + key[3]) else (key[1] + key[3]) # key = (smallest_x, smallest_y, largest_x, largest_y) # key = (x < key[0] ? x : key[0], y < key[1] ? y : key[1]) # break #rectangle_list.append((x,y,w,h)) # for r in rectangle_list: # if white_points is not None: # x,y,w,h = cv2.boundingRect(white_points) # rect = cv2.minAreaRect(white_points) # box = cv2.cv.BoxPoints(rect) # box = np.int0(box) # (x,y),radius = cv2.minEnclosingCircle(white_points) # center = (int(x),int(y)) # radius = int(radius) #cv2.circle(res,center,radius,(0,255,0),5) # cv2.drawContours(res,[box],0,(0,0,255),2) # cv2.rectangle(res,(x,y),(x+w,y+h),(255,255,255),5) # cv2.rectangle(mask,(x,y),(x+w,y+h),(255,255,255),5) mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) hsvMask = cv2.cvtColor(white_edges, cv2.COLOR_GRAY2BGR) side_comp = cv2.vconcat([res, mask, hsvMask, frame]) height, width, _ = side_comp.shape side_comp_res = cv2.resize(side_comp, (height / 2, width / 2)) # res2, contours, hierarchy = cv2.findContours() return side_comp_res
import numpy as np import cv2 from typing import Tuple filter_size = 13 assert filter_size % 2 == 1, 'Filter size must be a odd number' filter_half_size = filter_size // 2 filter_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (filter_size, filter_size)) == 1 fx = 520.9 fy = 521.0 cx = 325.1 cy = 249.7 def project_points(ids: np.ndarray, points: np.ndarray, depth_img: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: """ Projects the 2D points to 3D using the depth image and the camera instrinsic parameters. :param ids: A N vector point ids. :param points: A 2xN matrix of 2D points :param depth_img: The depth image. Divide pixel value by 5000 to get depth in meters. :return: A tuple containing a N vector and a 3xN vector of all the points that where successfully projected. """ cv2.imshow('depth', depth_img / np.max(depth_img)) n_points = len(ids)
def get_table_text_dict(self, test_gerber=False, save_dict=False, highlight_readable_paras=None, v_cut_save_path=None): """ save table text dict in a list """ print('I am working on extracting table information dictionary') table_num = 0 table_loc = [] table_dicts_group = [] pure_text_dict_group = [] # adjust contrast contrast_img = cv2.addWeighted(self.image, 1.3, self.blank_image, 1 - 1.3, 5) highlight_step_1 = self.blank_image.copy() gerber_file = get_file_type(self.image_path, test_gerber) if gerber_file: imgs, table_coo = read_table.extract_table_from_img( self.image_path) pure_table_image = np.zeros([ self.image_height + self.soft_margin, self.image_width + self.soft_margin, 3 ], self.image.dtype) for table in imgs: if not intersection_lines_detection(table): table_locate_info = self.get_pure_table_region( table_coo, table_num) # filling small table region prepare big table contours detector cv2.rectangle( pure_table_image, (table_locate_info[0], table_locate_info[1]), (table_locate_info[0] + table_locate_info[2], table_locate_info[1] + table_locate_info[3]), (0, 0, 255), thickness=-1) table_loc.append(table_locate_info) # cv2.rectangle(self.covered_text_image, (table_locate_info[0], table_locate_info[1]), # (table_locate_info[0] + table_locate_info[2], # table_locate_info[1] + table_locate_info[3]), # (0, 0, 0), thickness=-1) table_num += 1 else: table_num += 1 continue # print(self.covered_text_image.shape) # f = open('4S7MD161A0_table_loc.pkl', 'wb') # pickle.dump(table_loc, f) # f.close() # cv2.imwrite('pure_pure_table.png', pure_table_image) dilate_kernel = cv2.getStructuringElement(cv2.MORPH_OPEN, (7, 7)) dilate_image = cv2.dilate(pure_table_image, dilate_kernel, iterations=2) binary_table_region = get_binary(dilate_image, my_threshold=[45, 255]) table_edge_condition, table_region_contours = find_text_region( binary_table_region, cv2.RETR_EXTERNAL) print('I am working on pure text OCR') o_img = self.image.copy() background_color = get_dominant_color(o_img) for edge_num in range(len(table_edge_condition)): # draw big table contours cv2.drawContours(o_img, table_edge_condition, edge_num, background_color, thickness=3) pure_text_dict_group = pure_text_region(o_img, background_color, self.blank_image) # cv2.imwrite('pure_table.png', binary_table_region) print('I am working on tables OCR') i = 0 for edge_condition in table_edge_condition: sorted_edge_condition = sorted(edge_condition.tolist()) min_point = sorted_edge_condition[0] max_point = sorted_edge_condition[-1] cut_table = self.image[min_point[1]:max_point[1], min_point[0]:max_point[0]] c_x, c_y, c_z = cut_table.shape if c_x and c_y and c_z: table_ram = 'table_RAM' + str(i) + '.png' # table_ram = 'table_RAM.png' # print(table_ram) cv2.imwrite(table_ram, cut_table) i += 1 table_ram = ocr_preprocessed(table_ram) iso_table_dict = self.ocr_detector(table_ram, self.blank_image, self.soft_margin, min_point) if iso_table_dict: table_dicts_group.append(iso_table_dict) # os.remove(table_ram) if not table_dicts_group: print('not text') v_cut_detector(self.image, v_cut_save_path) elif not gerber_file: print('I am not gerber file using ocr') self.soft_margin = 0 try: iso_table_dict = self.ocr_detector(self.image_path, self.blank_image, self.soft_margin, [0, 0]) except Exception as e: print('OCR sever failed: {} Use backup solution'.format(e)) iso_table_dict = self.ocr_detector(self.image_path, self.blank_image, self.soft_margin, [0, 0], ocr_type='you_dao') if iso_table_dict: table_dicts_group.append(iso_table_dict) table_dicts_group.extend(pure_text_dict_group) if save_dict: # save table dictionary in pkl file print('save dictionary into pickle file') f_name = get_file_name(self.image_path) f_extension = get_extension(self.image_path) file = open(f_name + f_extension + '.pkl', 'wb') print('save path is:{}'.format(f_name + f_extension + '.pkl')) table_save_as_list = text_dict2text_list(table_dicts_group) print(table_save_as_list) pickle.dump(table_save_as_list, file) file.close() if highlight_readable_paras: print('highlight step 1') highlight_step_1 = cv2.addWeighted(contrast_img, 0.8, self.blank_image, 0.2, 3) f_name = get_file_name(self.image_path) f_extension = get_extension(self.image_path) cv2.imwrite(f_name + '_Marked_' + f_extension, highlight_step_1) return table_dicts_group, highlight_step_1
def handle_LBP(gray_img, sample_coord, block_size=(20, 60), similar_condi=0.85): """ function: handle_LBP(gray_img, sample_coord[, block_size=(20, 60)[, similar_condi=0.85]]): 計算原始圖像和 sample 的 LBP 相似度 parameter: gray_img: 調整大小後的灰階圖像 sample_coord: 所有 sample 位於原始圖像的位置(左上角座標) block_size: 和 handle_sample 的 block_size 相同 similar_condi: 相似度的門檻值, 默認 0.85, 範圍 [0, 1), float method: 1. 計算 sample LBP 值以及直方圖 2. 相似度比較去除最不相似的 sample (採取逐一比較的方式, 去除相似度最低的, 其餘的都當成 markers) (相似度最低的判斷為 當前相似個數 - 最小相似個數 > 全距 // 2) 3. 天空全部都標成 marker(最上面一行) 4. 侵蝕一次 return: markers: 二值化的圖像, 用來當成 watershed 的 markers """ markers = np.zeros(gray_img.shape, np.uint8) width, height = block_size # 儲存 每張 LBP 值的 直方圖列表 hist_list = list() for coord in sample_coord: y, x = coord target = gray_img[y:y + height, x:x + width] # 1. 計算 LBP 值(為了要使用 cv2.calcHist 函數, 要把圖像的資料類型轉成 np.uint8) lbp_img = lbp(target, 8, 1).astype(np.uint8) hist = cv2.calcHist([lbp_img], [0], None, [256], [0, 256]) hist_list.append(hist) # 畫出所有 sample 的位置 cv2.rectangle(gray_img, (x, y), (x + width, y + height), (255, 255, 255), 5) # cv2.imshow('sample region', gray_img) # 2. # 存放相似度結果的列表 similar_list = list() for i in range(0, len(hist_list)): cnt = -1 # 計算相似個數(採逐一比較, 自己和自己比一定相似, 所以要減一) for j in range(0, len(hist_list)): sim = cv2.compareHist(hist_list[i], hist_list[j], cv2.HISTCMP_CORREL) if sim >= similar_condi: cnt += 1 similar_list.append(cnt) # 當前的個數 - 最小相似個數 <= sample 數量 // 2 for index, coord in enumerate(sample_coord): y, x = coord if similar_list[index] - min(similar_list) <= (max(similar_list) - min(similar_list)) // 2: markers[y:y + height, x:x + width] = 255 cv2.rectangle(gray_img, (x, y), (x + width, y + height), (0, 0, 0), 2) # 加上天空的座標 for x in range(0, gray_img.shape[1], width): markers[10:10 + height, x + width:x - width] = 255 cv2.imshow('sample region', gray_img) # 3. kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) markers = cv2.erode(markers, kernel, iterations=1) # cv2.imshow('markers', markers) return markers
def process_HSV(image, to_be_detected, denoise_value): ''' This will process each image in HSV space, trying to detect blobs of the colors in to_be_detected image is an openCV HSV image. to_be_detected a list of dicts. the dicts contain 'h_lower', 'h_upper', 's_lower', 's_upper', 'v_lower', 'v_upper'. ''' # Split channels (hue, saturation, value) = cv2.split(image) # Next, find blobs of each color. # Set up an empty image to merge with merge_image = None if len(to_be_detected) < 1: return None # For each color cube: for cube in to_be_detected: # Filter all three channels # Filter Hue (_,hue_1) = cv2.threshold(hue, cube['h_lower'],1,cv2.THRESH_BINARY) (_,hue_2) = cv2.threshold(hue, cube['h_upper'],1,cv2.THRESH_BINARY_INV) # Combine filtered images # Hue range may wrap around 0. if cube['h_upper']<cube['h_lower']: hue_combined = hue_1 | hue_2 #hue_combined = hue_1 or hue_2 else: hue_combined = hue_1 & hue_2 #hue_combined = hue_1 and hue_2 # Filter Saturation (_,saturation_1) = cv2.threshold(hue, cube['s_lower'],1,cv2.THRESH_BINARY) (_,saturation_2) = cv2.threshold(hue, cube['s_upper'],1,cv2.THRESH_BINARY_INV) # Combine filtered images saturation_combined = saturation_1 | saturation_2 # Filter Value (_,value_1) = cv2.threshold(hue, cube['v_lower'],1,cv2.THRESH_BINARY) (_,value_2) = cv2.threshold(hue, cube['v_upper'],1,cv2.THRESH_BINARY_INV) # Combine filtered images value_combined = value_1 | value_2 # Combine combined filtered images filtered = (hue_combined & saturation_combined) & value_combined # Add filtered to the combined image if merge_image is None: merge_image = copy.deepcopy(filtered) else: merge_image = (merge_image | filtered) # Remove noise through a closing if not denoise_value == 0: denoised = cv2.morphologyEx(merge_image, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_RECT, (denoise_value,denoise_value))) denoised = cv2.morphologyEx(denoised, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (denoise_value,denoise_value))) else: denoised = merge_image # Detect blobs found = cv2.findContours(denoised, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) if found: contours, hierarchy = found # Return the blobs return contours else: return None