def time_processing(switch_target_processor, input_files): '''Time the processing of the test files''' from codetimer import CodeTimer from time import time startt = time() cnt = 0 for _ in range(100): for image_file in input_files: with CodeTimer("Read Image"): bgr_frame = cv2.imread(image_file) with CodeTimer("Main Processing"): switch_target_processor.process_image(bgr_frame) cnt += 1 deltat = time() - startt print("{0} frames in {1:.3f} seconds = {2:.2f} msec/call, {3:.2f} FPS". format(cnt, deltat, 1000.0 * deltat / cnt, cnt / deltat)) CodeTimer.outputTimers() return
def time_processing(cube_processor, input_files): '''Time the processing of the test files''' from codetimer import CodeTimer from time import time startt = time() cnt = 0 # Loop 100x over the files. This is needed to make it long enough # to get reasonable statistics. If we have 100s of files, we could reduce this. # Need the total time to be many seconds so that the timing resolution is good. for _ in range(100): for image_file in input_files: with CodeTimer("Read Image"): bgr_frame = cv2.imread(image_file) with CodeTimer("Main Processing"): cube_processor.process_image(bgr_frame) cnt += 1 deltat = time() - startt print("{0} frames in {1:.3f} seconds = {2:.2f} ms/call, {3:.2f} FPS".format( cnt, deltat, 1000.0 * deltat / cnt, cnt / deltat)) CodeTimer.output_timers() return
def _intersection(hesse_vec, pt1, pt2): """Finds the intersection of two lines given in Hesse normal form. Returns closest integer pixel locations. See https://stackoverflow.com/a/383527/5087436 """ with CodeTimer("_intersection"): # Compute the Hesse form for the lines rho1 = sqrt(hesse_vec.dot(hesse_vec)) norm1 = hesse_vec / rho1 hesse2 = _hesse_form(pt1, pt2) rho2 = sqrt(hesse2.dot(hesse2)) norm2 = hesse2 / rho2 cos1 = norm1[0] sin1 = norm1[1] cos2 = norm2[0] sin2 = norm2[1] denom = cos1 * sin2 - sin1 * cos2 x = (sin2 * rho1 - sin1 * rho2) / denom y = (cos1 * rho2 - cos2 * rho1) / denom res = round(array((x, y))).astype(int) return res
def johncarter_study(symbol): with CodeTimer('Prepare JC Squeeze data') as ct: df = jcdata.process_jcsqueeze(symbol) # draw chart jcchart.drawchart(symbol, df)
def process_jc_study(symbol): with CodeTimer('Prepare JC Squeeze data') as ct: df = jcsqueeze.process_jcsqueeze(symbol) # draw chart jcsqueeze_chart.drawchart(symbol, df)
def convex_polygon_fit(contour, nsides): '''Fit a polygon and then refine the sides. Refining only works if this a convex shape''' with CodeTimer("approxPolyDP_adaptive"): start_contour = approxPolyDP_adaptive(contour, nsides) if start_contour is None: # failed. Not much to do print('adapt failed') return None #hough_refine(contour, start_contour) #return start_contour return refine_convex_fit(contour, start_contour)
def hough_refine(contour, contour_fit): '''Refine a fit to a convex contour. Look for an approximation of the minimum bounding polygon. Each side is refined, without changing the other sides. The number of sides is not changed.''' x, y, w, h = cv2.boundingRect(contour) print("hough_refine: boundingRect", x, y, w, h) # include a 1 pixel border, just because offset_vec = numpy.array((x - 1, y - 1)) #con_shape = (w+2, h+2) #offset_vec = numpy.array((0,0)) shifted_con = contour_fit - offset_vec nsides = len(shifted_con) hesse_form = [] minmax = [1e6, -1e6, 1e6, -1e6] for ivrtx in range(nsides): ivrtx2 = (ivrtx + 1) % nsides hesse_vec = _hesse_form(shifted_con[ivrtx][0], shifted_con[ivrtx2][0]) # Hough uses separate rho, theta, so compute now rho = sqrt(hesse_vec.dot(hesse_vec)) theta = atan2(hesse_vec[1], hesse_vec[0]) print('hesse', rho, math.degrees(theta)) hesse_form.append((rho, theta)) minmax[0] = min(minmax[0], rho) minmax[1] = max(minmax[1], rho) minmax[2] = min(minmax[2], theta) minmax[3] = max(minmax[3], theta) print("rho theta range", minmax[0], minmax[1], math.degrees(minmax[2]), math.degrees(minmax[3])) print('contour_fit', shifted_con) return None contour_plot = numpy.zeros(shape=(480, 640), dtype=numpy.uint8) cv2.drawContours(contour_plot, [ contour, ], -1, 255, 1) # the binning does affect the speed, so tune it.... with CodeTimer("HoughLines"): lines = cv2.HoughLines(contour_plot, 1, numpy.pi / 180, threshold=10) if lines is None or len(lines) < nsides: print("Hough found too few lines") return None return None
def main(): parser = argparse.ArgumentParser( description='bgrtohsv_inrange test program') parser.add_argument('files', nargs='*', help='input files') args = parser.parse_args() # Color threshold values, in HSV space low_limit_hsv = numpy.array((70, 60, 30), dtype=numpy.uint8) high_limit_hsv = numpy.array((100, 255, 255), dtype=numpy.uint8) #if args.no_opencl: # print('Disabling OpenCL') # cv2.ocl.setUseOpenCL(False) # prime the routines for more accurate timing bgr_frame = cv2.imread(args.files[0]) with CodeTimer("TableInit"): lookup_table = bgrtohsv_inrange_preparetable(low_limit_hsv, high_limit_hsv) print('lookup table:', lookup_table.shape) func_out = numpy.empty(shape=bgr_frame.shape[0:2], dtype=numpy.uint8) table_out = numpy.empty(shape=bgr_frame.shape[0:2], dtype=numpy.uint8) hsv_frame = numpy.empty(shape=bgr_frame.shape, dtype=numpy.uint8) thres_frame = numpy.empty(shape=bgr_frame.shape[0:2], dtype=numpy.uint8) for _ in range(100): for image_file in args.files: bgr_frame = cv2.imread(image_file) with CodeTimer("OpenCV"): bgrtohsv_inrange_cv2(bgr_frame, low_limit_hsv, high_limit_hsv, hsv_frame, thres_frame) with CodeTimer("FunctionConversion"): bgrtohsv_inrange(bgr_frame, low_limit_hsv, high_limit_hsv, func_out) with CodeTimer("TableConversion"): bgrtohsv_inrange_table(lookup_table, bgr_frame, table_out) ##print(image_file, "equal =", checkEqualHSV(cv2Out, func_out)) if not numpy.array_equal(thres_frame, func_out): print(image_file, " function conversion failed") if not numpy.array_equal(thres_frame, table_out): print(image_file, " table conversion failed") CodeTimer.outputTimers() return
def refine_convex_fit(contour, contour_fit): '''Refine a fit to a convex contour. Look for an approximation of the minimum bounding polygon. Each side is refined, without changing the other sides. The number of sides is not changed.''' angle_step = pi / 180.0 nsides = len(contour_fit) for iside1 in range(nsides): iside2 = (iside1 + 1) % nsides iside3 = (iside2 + 1) % nsides iside0 = (iside1 - 1) % nsides hesse_vec = _hesse_form(contour_fit[iside1][0], contour_fit[iside2][0]) midpt = (contour_fit[iside1][0] + contour_fit[iside2][0]) / 2.0 delta = contour_fit[iside1][0] - contour_fit[iside2][0] line_length = sqrt(delta.dot(delta)) start_area = cv2.contourArea(contour_fit) best_area = None best_pts = None best_offset = None start_angle = atan2(hesse_vec[1], hesse_vec[0]) test_contour = copy.copy(contour_fit) for iangle in range(-5, 6): # step angle by -5 to 5 inclusive # for iangle in range(-3, 3, 3): # step angle by -5 to 5 inclusive angle = start_angle + iangle * angle_step perp_unit_vec = array([cos(angle), sin(angle)]) midpt_dist = dot(midpt, perp_unit_vec) perp_dists = contour.dot(perp_unit_vec) min_dist = amin(perp_dists) - midpt_dist max_dist = amax(perp_dists) - midpt_dist offset = min_dist if abs(min_dist) < abs(max_dist) else max_dist if abs(offset) > 20: print("offset too big", offset) continue new_hesse = (midpt.dot(perp_unit_vec) + offset) * perp_unit_vec # compute the intersections with the curve intersection1 = _intersection(new_hesse, contour_fit[iside0][0], contour_fit[iside1][0]) intersection2 = _intersection(new_hesse, contour_fit[iside2][0], contour_fit[iside3][0]) test_contour[iside1][0] = intersection1 test_contour[iside2][0] = intersection2 with CodeTimer("contourArea"): area = cv2.contourArea(test_contour) - start_area # print("area", iside1, iangle, offset, area, _delta_area(line_length, offset, iangle * angle_step)) # intersection1 = contour_fit[iside1][0] # intersection2 = contour_fit[iside2][0] # area = iangle**2 if best_area is None or area < best_area[0]: best_area = (area, iangle) best_pts = (intersection1, intersection2) # print('new best', iside1, iangle, offset, area) if best_offset is None or abs(offset) < best_offset[0]: best_offset = (abs(offset), iangle) best_pts = (intersection1, intersection2) # print('new best', iside1, iangle, offset, area) #if best_offset[1] != best_area[1]: # print("Best offset and best area disagree") if best_pts is not None: contour_fit[iside1][0] = best_pts[0] contour_fit[iside2][0] = best_pts[1] return contour_fit