Python Forum
How to return values from For Loop via return in a function
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to return values from For Loop via return in a function
#11
(Jan-05-2019, 06:21 PM)stullis Wrote: Okay, let's track down the problem. Add a print() call to main to see what data is in c:

def main():
  c = detected_objects_2()
  print(c)
   
  for value in c:
    if value == "turnLeft":
      print("Turn Left is working!!!")
    elif value == "turnRight":
      print("Turn Right is working!!!")
    else:
      print("NO DETECTION at all!!!")  
If the data in c is not what you expect, then review vis_util.visualize_boxes_and_labels_on_image_array() to see what it returns.

I marked the added sides with as Added These with commenting. I only made some small edition to get result to be in my python file

visualization_utils.py function I made small edition
def visualize_boxes_and_labels_on_image_array(
    image,
    boxes,
    classes,
    scores,
    category_index,
    instance_masks=None,
    instance_boundaries=None,
    keypoints=None,
    use_normalized_coordinates=False,
    max_boxes_to_draw=20,
    min_score_thresh=.5,
    agnostic_mode=False,
    line_thickness=4,
    groundtruth_box_visualization_color='black',
    skip_scores=False,
    skip_labels=False):
  """Overlay labeled boxes on an image with formatted scores and label names.

  This function groups boxes that correspond to the same location
  and creates a display string for each detection and overlays these
  on the image. Note that this function modifies the image in place, and returns
  that same image.

  Args:
    image: uint8 numpy array with shape (img_height, img_width, 3)
    boxes: a numpy array of shape [N, 4]
    classes: a numpy array of shape [N]. Note that class indices are 1-based,
      and match the keys in the label map.
    scores: a numpy array of shape [N] or None.  If scores=None, then
      this function assumes that the boxes to be plotted are groundtruth
      boxes and plot all boxes as black with no classes or scores.
    category_index: a dict containing category dictionaries (each holding
      category index `id` and category name `name`) keyed by category indices.
    instance_masks: a numpy array of shape [N, image_height, image_width] with
      values ranging between 0 and 1, can be None.
    instance_boundaries: a numpy array of shape [N, image_height, image_width]
      with values ranging between 0 and 1, can be None.
    keypoints: a numpy array of shape [N, num_keypoints, 2], can
      be None
    use_normalized_coordinates: whether boxes is to be interpreted as
      normalized coordinates or not.
    max_boxes_to_draw: maximum number of boxes to visualize.  If None, draw
      all boxes.
    min_score_thresh: minimum score threshold for a box to be visualized
    agnostic_mode: boolean (default: False) controlling whether to evaluate in
      class-agnostic mode or not.  This mode will display scores but ignore
      classes.
    line_thickness: integer (default: 4) controlling line width of the boxes.
    groundtruth_box_visualization_color: box color for visualizing groundtruth
      boxes
    skip_scores: whether to skip score when drawing a single detection
    skip_labels: whether to skip label when drawing a single detection

  Returns:
    uint8 numpy array with shape (img_height, img_width, 3) with overlaid boxes.
  """
  # Create a display string (and color) for every box location, group any boxes
  # that correspond to the same location.
  box_to_display_str_map = collections.defaultdict(list)
  box_to_color_map = collections.defaultdict(str)
  box_to_instance_masks_map = {}
  box_to_instance_boundaries_map = {}
  box_to_keypoints_map = collections.defaultdict(list)
  if not max_boxes_to_draw:
    max_boxes_to_draw = boxes.shape[0]
  for i in range(min(max_boxes_to_draw, boxes.shape[0])):
    if scores is None or scores[i] > min_score_thresh:
      box = tuple(boxes[i].tolist())
      if instance_masks is not None:
        box_to_instance_masks_map[box] = instance_masks[i]
      if instance_boundaries is not None:
        box_to_instance_boundaries_map[box] = instance_boundaries[i]
      if keypoints is not None:
        box_to_keypoints_map[box].extend(keypoints[i])
      if scores is None:
        box_to_color_map[box] = groundtruth_box_visualization_color
      else:
        display_str = ''
        if not skip_labels:
          if not agnostic_mode:
            if classes[i] in category_index.keys():
              class_name = category_index[classes[i]]['name']
              #Added These
              if class_name == 'turnLeft':
                print("Turn Left")
              if class_name == 'turnRight':
                print("Turn Right")
            else:
              class_name = 'N/A'
            display_str = str(class_name)
        if not skip_scores:
          if not display_str:
            display_str = '{}%'.format(int(100*scores[i]))
          else:
            display_str = '{}: {}%'.format(display_str, int(100*scores[i]))
        box_to_display_str_map[box].append(display_str)
        if agnostic_mode:
          box_to_color_map[box] = 'DarkOrange'
        else:
          box_to_color_map[box] = STANDARD_COLORS[
              classes[i] % len(STANDARD_COLORS)]

  # Draw all boxes onto image.
  for box, color in box_to_color_map.items():
    ymin, xmin, ymax, xmax = box
    if instance_masks is not None:
      draw_mask_on_image_array(
          image,
          box_to_instance_masks_map[box],
          color=color
      )
    if instance_boundaries is not None:
      draw_mask_on_image_array(
          image,
          box_to_instance_boundaries_map[box],
          color='red',
          alpha=1.0
      )
    draw_bounding_box_on_image_array(
        image,
        ymin,
        xmin,
        ymax,
        xmax,
        color=color,
        thickness=line_thickness,
        display_str_list=box_to_display_str_map[box],
        use_normalized_coordinates=use_normalized_coordinates)
    if keypoints is not None:
      draw_keypoints_on_image_array(
          image,
          box_to_keypoints_map[box],
          color=color,
          radius=line_thickness / 2,
          use_normalized_coordinates=use_normalized_coordinates)

  return image, class_name # #Added These - class_name
I will be very happy if you would assist me to solve this issue, I work on these like 6 days already. I still don't know what is the cause of it. I am not so good in python; so if I will be very happy if you assist me more, thank you very much.

You can check the whole tensorflow models api file which is written in python already: Tensorflow Models API - Models Folder for Object Detection
Reply
#12
UPDATE:

What I wanted to do was this simply:
"Return a value from for loop inside of a function in python"

I wrote a simple testing code to test this append in python as the way I want to achieve with every possibilities to print / return a value, and the result is same that nothing is returning at all...

#a = []
def append_try():
    a = []
    for i in range(2):
        a.append(i)
    #print(a)    
    return a


def main():
    b = append_try()
    if b == "'[0]'":
        print("0")
    elif b == "'[1]'":
        print("1")
    elif b == "'[0, 1]'":
        print("2")
    else:
        print("it is not working")

main()
What I got from print is a big "it is not working". Thus, it is not working with append. Is there any other way to do the thing I want ? thank you.
Reply
#13
The test code isn't working because you're comparing a list to a string. Removing the quotations makes it work:

#a = []
def append_try():
    a = []
    for i in range(2):
        a.append(i)
    #print(a)
    return a


def main():
    b = append_try()
    if b == [0]:
        print("0")
    elif b == [1]:
        print("1")
    elif b == [0, 1]:
        print("2")
    else:
        print("it is not working")

main()
As for why your code isn't returning the b values, I suspect it's line 82 of visualize_boxes_and_labels_on_image_array(). Your conditional is nested under the conditional started on line 82. All the prior conditionals I can verify as True, but not that one. You said you made an addition to the code; is this all custom code or is visualize_boxes_and_labels_on_image_array() from a third party module?
Reply
#14
(Jan-07-2019, 02:43 AM)stullis Wrote: The test code isn't working because you're comparing a list to a string. Removing the quotations makes it work:

#a = []
def append_try():
    a = []
    for i in range(2):
        a.append(i)
    #print(a)
    return a


def main():
    b = append_try()
    if b == [0]:
        print("0")
    elif b == [1]:
        print("1")
    elif b == [0, 1]:
        print("2")
    else:
        print("it is not working")

main()
As for why your code isn't returning the b values, I suspect it's line 82 of visualize_boxes_and_labels_on_image_array(). Your conditional is nested under the conditional started on line 82. All the prior conditionals I can verify as True, but not that one. You said you made an addition to the code; is this all custom code or is visualize_boxes_and_labels_on_image_array() from a third party module?

Without any modification, the original visualize_boxes_and_labels_on_image_array() only returns the image values to use so we can see the detected object's name on the cv2 image only, so it doesn't give you the class_name directly so it cannot be used in your code. The reason, I want to use a return value to python directly; because I want to send that values to ROS program as a string so I can make my robot to turn left turn right etc.

If I didn't make any modification what to append ? We want to append the class_name to return its values to be used in the robot to turn

Note:
ROS is not using opencv directly (you need to use nodes which is very complex in coding section) so I thought if I only send these b_values to ROS as string then I can send that values to my robot.


I wrote this code (according to old tensorflow models api tutorial which is quite different than the 2018 ones, I shared with you in this thread) which is detecting images again without any cv2 but gives the every image in the test image file with using the original or modified version of visualize_boxes_and_labels_on_image_array() but even these, you still cannot use that detection value names directly or I don't know how to pull that class name from this line of code:
print ([category_index.get(value) for index,value in enumerate(classes[0]) if scores[0,index] > 0.5])
The main code
with detection_graph.as_default():
  with tf.Session(graph=detection_graph) as sess:
    sess.run(tf.global_variables_initializer())
    img = 'test1'
    for image_path in TEST_IMAGE_PATHS:
      image = Image.open(image_path)
      image_np = load_image_into_numpy_array(image)
      # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
      image_np_expanded = np.expand_dims(image_np, axis=0)
      image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
      # Each box represents a part of the image where a particular object was detected.
      boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
      scores = detection_graph.get_tensor_by_name('detection_scores:0')
      classes = detection_graph.get_tensor_by_name('detection_classes:0')
      num_detections = detection_graph.get_tensor_by_name('num_detections:0')

      (boxes, scores, classes, num_detections) = sess.run(
          [boxes, scores, classes, num_detections],
          feed_dict={image_tensor: image_np_expanded})

      vis_util.visualize_boxes_and_labels_on_image_array(
          image_np,
          np.squeeze(boxes),
          np.squeeze(classes).astype(np.int32),
          np.squeeze(scores),
          category_index,
          use_normalized_coordinates=True,
          line_thickness=8)
      plt.figure(figsize=IMAGE_SIZE)
      plt.imsave('RESULTS/' + str(img) + '.jpg', image_np)
      img += '1'

      # Return found objects
      #print([category_index.get(i) for i in classes[0]])
      #print(boxes.shape)
      #print(num_detections)
      print ([category_index.get(value) for index,value in enumerate(classes[0]) if scores[0,index] > 0.5])
You get this result:

TurnRight
[{'id': 2, 'name': 'turnRight'}]
TurnLeft
[{'id': 1, 'name': 'turnLeft'}]
TurnRight
[{'id': 2, 'name': 'turnRight'}]
TurnRight
[{'id': 2, 'name': 'turnRight'}]
TurnLeft
[{'id': 1, 'name': 'turnLeft'}]
TurnRight
[{'id': 2, 'name': 'turnRight'}]

#Or you this one only without any modification
[{'id': 2, 'name': 'turnRight'}]
[{'id': 1, 'name': 'turnLeft'}]
[{'id': 2, 'name': 'turnRight'}]
[{'id': 2, 'name': 'turnRight'}]
[{'id': 1, 'name': 'turnLeft'}]
[{'id': 2, 'name': 'turnRight'}]
In the new example, this line of code is printing the above statements:
print ([category_index.get(value) for index,value in enumerate(classes[0]) if scores[0,index] > 0.5])
How can we use this line of code too ? or apply append here ?
Reply
#15
There's nothing wrong with changing third party code. I just wanted to know.

I am curious about application though; partly because I'm not an expert with Tensorflow. Based on what I do know, it seems that you want to take a visual input from an onboard camera and evaluate obstacles in the way. Does this function weigh the objects it identifies based on distance? If not, then the robot may still collide with obstacles because its turns may occur at incorrect times. The problem being that a picture is 2D so basing 3d movement on it is tricky at best; it only works for us because we have two eyes.

The function evidently adds boxes to the image data. Would it be possible to evaluate the output image for those changes and base the turns on that?

I just noticed something about your class argument. The data passed in is:

np.squeeze(classes).astype(np.int32)
To me, that indicates that all the data returned in that structure would be converted to 32-bit integers. Then, in the body of the code, you're checking if the class equals "turnRight", which is a string. Can you verify that the data returned is still a string?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Sympy nonlinsolve does not return explicit solution axelle 0 74 Jan-08-2021, 02:56 PM
Last Post: axelle
  A function to return only certain columns with certain string illmattic 2 536 Jul-24-2020, 12:57 PM
Last Post: illmattic
  Match string return different cell string Kristenl2784 0 248 Jul-20-2020, 07:54 PM
Last Post: Kristenl2784
  Basic storage of function values for monte carlo simulation glidecode 1 462 Apr-15-2020, 01:41 AM
Last Post: jefsummers
  how to get x values based on y-axis values from curvefit function python_newbie09 1 932 Sep-19-2019, 02:09 AM
Last Post: scidam
  Comparing Values Resulting from Function Outputs firebird 0 563 Jul-25-2019, 05:16 AM
Last Post: firebird
  Return ERROR when installing pyopencl Helcio_Sarabando 1 1,673 Sep-08-2018, 11:23 PM
Last Post: Larz60+
  Converting days to years in loop while computing values across grid cells Lightning1800 2 1,162 May-15-2018, 08:44 PM
Last Post: Lightning1800
  How get values from ACF function franromanos6 2 2,710 Mar-13-2018, 03:44 PM
Last Post: franromanos6
  Newbie question to return only the index of a dataframe zydjohn 0 1,109 Jan-22-2018, 03:40 PM
Last Post: zydjohn

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020