Пример #1
0
def check_corners(worm_matrix, length):
    height, width = worm_matrix.shape
    pixel_dense = {}
    worm_min = np.inf
    pop_list = []
    for y in range(height):
        for x in range(width):
            if worm_matrix[y, x]:
                worm_near = ci.wormNearPixel(worm_matrix, y, x, search_range=1)
                if worm_near < worm_min:
                    pixel_dense[(y, x)] = worm_near
                    worm_min = worm_near
                    for item in pixel_dense:
                        if pixel_dense[item] > worm_min:
                            pop_list.append(item)
    for item in pop_list:
        pixel_dense.pop(item)
        while item in pop_list:
            pop_list.remove(item)
    distance_dict = {}
    for pix1 in pixel_dense:
        for pix2 in pixel_dense:
            for pix3 in pixel_dense:
                if pix1 != pix2 and pix1 != pix3 and pix2 != pix3:
                    dist_sum = ci.pointDistance(pix1, pix2) + ci.pointDistance(
                        pix1, pix3) + ci.pointDistance(pix2, pix3)
                    if dist_sum > length * CORNER_DISTANCE_CONSTANT:
                        return False

    return True
Пример #2
0
def cleanSmallLoops(point_list):
  """
  Removes small groupings of points from the point_list and returns the list

  Args:
    point_list: A list of points

  Returns:
    point_list: The list with any small loops at the end closed
  """

  #Find the point that starts the circle
  for i in range(len(point_list)):

    point1 = point_list[i]
    if ci.checkClosePoint(point1,point_list):
      break
  point_dict = {}

  #Look for the most distant point
  for j in range(i,len(point_list)):
    point_dict[j] = ci.pointDistance(point1,point_list[j])
  indx = max(point_dict, key=point_dict.get)

  #Remove the points following that distant point
  if indx - i < SMALLEST_LOOP:

    return point_list[0:indx]
  else:
    return point_list
Пример #3
0
def sortPoints(point_list):
    """
  Put points in a recognizable order. The first point should be closest to (0,0)

  Args:
    point_list: The list of points to sort

  Returns:
    point_list: The sorted list of points
  """
    first_distance = ci.pointDistance(point_list[0], (0, 0))
    last_distance = ci.pointDistance(point_list[-1], (0, 0))
    if first_distance < last_distance:
        return point_list
    else:
        point_list.reverse()
        return point_list
Пример #4
0
def calcTravel(x1s,y1s,x2s,y2s):
  """!!!!!Find something better for this!!!!!"""
  total_distance = 0
  for i in range(len(x1s)-1):
    travel_dif = ci.pointDistance(((x1s[i]+x2s[i])/2,(y1s[i]+y2s[i])/2),((x1s[i+1]+x2s[i+1])/2,(y1s[i+1]+y2s[i+1])/2))
    if travel_dif > 2:
      total_distance+=travel_dif
  return total_distance
Пример #5
0
  def total_distance(self, other_cluster):
    """
    Finds the total distance two clusters cover
    The first point of the next cluster will be linked to the last point of this cluster

    other_cluster: The cluster to attach at the end of this one
    """
    return self.cml_distance + other_cluster.cml_distance + ci.pointDistance(self.point_list[-1], other_cluster.point_list[0])
Пример #6
0
def translateDistances(distance_list,prior_direction,next_point,worm_matrix,point_list):
  """
  Determines which possible directions could be possible to move in based on inputs

  Args:
    distance_list: A list of values with the index representing a direction and the value representing how 'good' of a path this is
    prior_direction: The direction moved in previously
    next_point: The point to move from
    worm_matrix: The matrix describing what is 'worm' and what isn't
    point_list: The list of all previous points

  Returns:
    A direction in which to move in based on an evenly segmented circle
  """
  possible_directions=[]
  if distance_list[0]==min(distance_list):
    possible_directions.extend([2,6])
  if distance_list[1]==min(distance_list):
    possible_directions.extend([0,4])
  if distance_list[3]==min(distance_list):
    possible_directions.extend([1,5])
  if distance_list[2]==min(distance_list):
    possible_directions.extend([3,7])

  limited_directions = []
  for i in range(-2,3):
    v =prior_direction+i
    if v<0:
      v+=8
    if v>7:
      v-=8
    limited_directions.append(v)
  select_direct = intersection(possible_directions,limited_directions)
  backup = []
  for item in select_direct:
    direction_list = [(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1)]
    test_change = direction_list[item]
    if not worm_matrix[next_point[0]+test_change[0],next_point[1]+test_change[1]]:
      select_direct.remove(item)
      backup.append(item)

  if len(select_direct) == 0:
    return backup[0]

  elif len(select_direct) > 1:
    direction_list = [(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1)]
    point_distance = {}
    for item in select_direct:
      test_change = direction_list[item]
      coord1 = (next_point[0]+test_change[0],next_point[1]+test_change[1])
      test_change = direction_list
      sumv=0
      for coord2 in point_list:
        sumv+=ci.pointDistance(coord1,coord2)
      point_distance[item] = sumv
    return max(point_distance,key=point_distance.get)
  return select_direct[0]
Пример #7
0
def trajSinIndex(point_list):
  step_length = []
  turn_angle = []
  for i in range(len(point_list)-1):
    step_length.append(ci.pointDistance(point_list[i],point_list[i+1]))
    if i != 0:
      turn_angle.append(sc.getAngle(point_list[i-1],point_list[i],point_list[i+1]))
  sigma = np.nanstd(np.array(turn_angle))
  q = np.nanmean(np.array(step_length))
  return 1.18 * sigma / np.sqrt(q)
Пример #8
0
  def connect(self, other_point):
    """
    Creates and returns a new cluster with the new point added to the end of this cluster
    """
    total_size = self.size + other_point.size
    point_list = self.point_list + other_point.point_list

    total_distance = self.cml_distance + other_point.cml_distance + ci.pointDistance(self.point_list[-1], other_point.point_list[0])

    return cluster(point_list,total_size,total_distance)
Пример #9
0
def getCmlDistance(worm_matrix, grayscale_matrix, worm_path=None):
  """
  Segments the worm into point_num clusters, then finds the total change in slope.
  """
  wormFront = ci.findFront(worm_matrix)
  skelList = lazySkeleton(worm_matrix)
  sum = 0
  for i in range(0,len(skelList)-1,1):
    sum += ci.pointDistance(skelList[i],skelList[i+1])
  return sum
Пример #10
0
 def connection(self,other_point):
   """
   Determines whether two clusters can form a valid connection
   ---
   other_point: The following cluster
   """
   total_size = self.size + other_point.size
   total_distance = self.cml_distance + other_point.cml_distance
   total_distance += ci.pointDistance(self.point_list[-1], other_point.point_list[0])
   if total_size <= MAX_SIZE and total_distance <= MAX_DISTANCE:
     return True
   else:
     return False
Пример #11
0
 def midpoint(self):
   """
   Returns an (x,y) that is equally distant from either end of the cluster, moving along points in the cluster
   """
   mes_distance = 0
   i = 1
   point= self.point_list[0]
   prev_point = point
   while mes_distance < self.cml_distance/2:
     point = self.point_list[i]
     mes_distance += ci.pointDistance(prev_point,point)
     i+=1
   return point
Пример #12
0
def allSingleAnalysis(worm_location, img_name, use_ci=True):
    """
  Collects all data from a worm image

  Args:
    worm_location: The folder that the image is located in
    img_name: The image of the worm
    use_ci: Whether to use worm_location as a file path or as a raw image

  Returns:
    outnumpy: Numpy array of data
  """
    try:
        # Get basic information about the image
        parsed_name = img_name.split("_")
        vid_id = parsed_name[1]
        frame = parsed_name[2]
        worm_id = parsed_name[3]
        x1 = parsed_name[5]
        y1 = parsed_name[6]
        x2 = parsed_name[7]
        y2 = parsed_name[8].split(".")[0]

        # Make the basic information: worm matrix, grayscale matrix, and skeleton
        if use_ci:
            worm_dict, grayscale_matrix = ci.getWormMatrices(worm_location +
                                                             "/" + img_name)
        else:
            worm_dict, grayscale_matrix = ci.getFilelessWormMatrices(
                worm_location)
        worm_matrix = ci.findCenterWorm(worm_dict)
        skel_list = sc.lazySkeleton(worm_matrix)

        area = np.sum(worm_matrix)

        # Create a matrix with only the color values of worm pixels
        mult_matrix = np.multiply(worm_matrix, grayscale_matrix)
        # Set all pixels that aren't worm to nan
        mult_matrix[mult_matrix == 0] = np.nan
        # Take the average ignoring nan
        shade = np.nanmean(mult_matrix)

        # Create Simplified worm skeleton
        skel_simple = sc.makeFractionedClusters(skel_list, 7)
        # Take cumulative angle of simplified skeleton
        cml_angle = sc.getCmlAnglePoints(skel_simple)

        length = 0
        for i in range(0, len(skel_list) - 1, 1):
            length += ci.pointDistance(skel_list[i], skel_list[i + 1])

        # Find Max Width
        width_point = {}
        for i in range(0, len(skel_list)):
            point = skel_list[i]
            x = point[0]
            y = point[1]
            width_point[point] = estimateMaxWidth(point, worm_matrix)
        max_width = width_point[max(width_point, key=width_point.get)]

        mid_width = width_point[skel_list[round(len(skel_list) / 2)]]

        # Get Diagonals
        diagonals = sc.getDiagonalNum(worm_matrix, grayscale_matrix)

        # Get simplified skeleton coordinates
        skel_simple = sc.makeFractionedClusters(skel_list, 5)
        sorted_list = sortPoints(skel_simple)

        point1_x = sorted_list[0][0]
        point1_y = sorted_list[0][1]
        point2_x = sorted_list[1][0]
        point2_y = sorted_list[1][1]
        point3_x = sorted_list[2][0]
        point3_y = sorted_list[2][1]
        point4_x = sorted_list[3][0]
        point4_y = sorted_list[3][1]
        point5_x = sorted_list[4][0]
        point5_y = sorted_list[4][1]

        outnumpy = np.array([
            frame, x1, y1, x2, y2, worm_id, area, shade, cml_angle, length,
            max_width, mid_width, diagonals, point1_x, point1_y, point2_x,
            point2_y, point3_x, point3_y, point4_x, point4_y, point5_x,
            point5_y
        ])
        wc.check_worm(worm_dict, worm_matrix, outnumpy, skel_list)

    except Exception as E:
        # Show that something went wrong in console
        if SHOW_INVALID:
            print(img_name, "is invalid")
            print(E)

        # Show that the data is invalid
        outnumpy = np.array([
            frame, x1, y1, x2, y2, worm_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0
        ])
    return outnumpy
Пример #13
0
def getValuesFrom(day,header,cur_data):

  for i in range(len(header)):
    if header[i] == "Worm ID":
      id_head = i
    elif header[i] == "Area":
      area_head = i
    elif header[i] == "Shade":
      shade_head = i
    elif header[i] == "Cumulative Angle":
      cml_angle_head = i
    elif header[i] == "Length":
      l_head = i
    elif header[i] == "Max Width":
      mxw_head = i
    elif header[i] == "Mid Width":
      mdw_head = i
    elif header[i] == "Diagonals":
      dgl_head = i
    elif header[i] == "x1":
      x1_head = i
    elif header[i] == "x2":
      x2_head = i
    elif header[i] == "y1":
      y1_head = i
    elif header[i] == "y2":
      y2_head = i
    elif header[i] == "# Video Frame" or header[i] == "Video Frame":
      frame_head = i

  avg_area = sum(cur_data[area_head])/len(cur_data[area_head])
  avg_shade = sum(cur_data[shade_head])/len(cur_data[shade_head])
  angle_variance = np.var(cur_data[cml_angle_head])
  avg_length = sum(cur_data[l_head])/len(cur_data[l_head])
  avg_mxw = sum(cur_data[mxw_head])/len(cur_data[mxw_head])
  avg_mdw = sum(cur_data[mdw_head])/len(cur_data[mdw_head])
  diagonal_variance = np.var(cur_data[dgl_head])

  # Approximate total traveled distance
  # TODO: Threshold of change (<2.5?)
  total_travel = calcTravel(cur_data[x1_head],cur_data[y1_head],cur_data[x2_head],cur_data[y2_head])

  travel_speed = total_travel / (cur_data[0][-1] - cur_data[0][0])

  # TODO: Traja... stuff?
  x_arr = []
  y_arr = []
  time_arr = []
  point_arr = []
  for i in range(len(cur_data[x1_head])):
    x_arr.append((cur_data[x1_head][i] + cur_data[x2_head][i])/2)
    y_arr.append((cur_data[y1_head][i] + cur_data[y2_head][i])/2)
    time_arr.append(cur_data[frame_head][i])
    point_arr.append([x_arr[-1],y_arr[-1]])

  # TODO: Check if able to set noise of movement (extended or smaller groupings of motion)
  df = trj.TrajaDataFrame({'x':x_arr,'y':y_arr,'time':time_arr})
  df_derivs = df.traja.get_derivatives()


  if SHOW_MOTION:
    plt.plot(df['x'],df['y'])

  avg_accel = np.nanmean(df_derivs["acceleration"])
  max_accel = np.nanmax(df_derivs["acceleration"])
  max_speed = np.nanmax(df_derivs["speed"])
  avg_speed = np.nanmean(df_derivs["speed"])

  point0 = ((cur_data[x1_head][0] + cur_data[x2_head][0])/2, (cur_data[y1_head][0] + cur_data[y2_head][0])/2)
  last_point = ((cur_data[x1_head][-1] + cur_data[x2_head][-1])/2, (cur_data[y1_head][-1] + cur_data[y2_head][-1])/2)
  rvr_sinuosity_index = total_travel / ci.pointDistance(point0,last_point)
  #try:
  clustP = sc.makeFractionedClusters(point_arr,8)
  if SHOW_MOTION:
    x, y = zip(*clustP)
    plt.scatter(x,y)
    plt.show()

  sinuosity_index = trajSinIndex(clustP)

  #except:
  #  return np.array([float(day),cur_data[id_head][0],avg_area,avg_shade,angle_variance,avg_length,avg_mxw,avg_mdw,diagonal_variance,total_travel,travel_speed,avg_speed,max_speed,max_accel,avg_accel,rvr_sinuosity_index,sinuosity_index])

  return np.array([float(day),cur_data[id_head][0],avg_area,avg_shade,angle_variance,avg_length,avg_mxw,avg_mdw,diagonal_variance,total_travel,travel_speed,avg_speed,max_speed,max_accel,avg_accel,rvr_sinuosity_index,sinuosity_index])