Skip to content

Commit

Permalink
dev version 190630_1700
Browse files Browse the repository at this point in the history
  • Loading branch information
lbborkowski committed Jun 30, 2019
1 parent f4feb94 commit ffb0a59
Showing 1 changed file with 10 additions and 189 deletions.
199 changes: 10 additions & 189 deletions WindTurbineDetector_dev2.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -617,8 +617,8 @@
},
"source": [
"# Path to frozen detection graph. This is the actual model that is used for the object detection.\n",
"#PATH_TO_FROZEN_GRAPH = '/content/wind-turbine-detector/WTDetectorModel/frozen_inference_graph.pb'\n",
"PATH_TO_FROZEN_GRAPH = '/content/wind-turbine-detector/trainedWTDetector/frozen_inference_graph.pb' # Uncomment this line to run inference (without training) using provided pre-trained model\n",
"PATH_TO_FROZEN_GRAPH = '/content/wind-turbine-detector/WTDetectorModel/frozen_inference_graph.pb'\n",
"#PATH_TO_FROZEN_GRAPH = '/content/wind-turbine-detector/trainedWTDetector/frozen_inference_graph.pb' # Uncomment this line to run inference (without training) using provided pre-trained model\n",
"\n",
"# List of the strings that is used to add correct label for each box.\n",
"PATH_TO_LABELS = '/content/wind-turbine-detector/annotations/label_map.pbtxt'"
Expand Down Expand Up @@ -714,7 +714,7 @@
},
"source": [
"#### Inference function\n",
"Perform inferance one image at a time"
"Perform inference one image at a time"
]
},
{
Expand Down Expand Up @@ -827,9 +827,7 @@
"colab": {}
},
"source": [
"ii=0\n",
"for image_path in TEST_IMAGE_PATHS:\n",
" ii+=1\n",
" image = Image.open(image_path)\n",
" # the array based representation of the image will be used later in order to prepare the\n",
" # result image with boxes and labels on it.\n",
Expand All @@ -848,11 +846,9 @@
" instance_masks=output_dict.get('detection_masks'),\n",
" use_normalized_coordinates=True,\n",
" line_thickness=8)\n",
" fig = plt.figure(figsize=IMAGE_SIZE)\n",
" plt.figure(figsize=IMAGE_SIZE)\n",
" plt.axis('off')\n",
" #plt.savefig('%s_%02d_%02d.jpg' % (image_path.replace('.jpg',''), ii, jj),bbox_inches='tight')\n",
" plt.imshow(image_np)\n",
" #fig.savefig('valid_%02d.png' % (ii), bbox_inches='tight', pad_inches=0)"
" plt.imshow(image_np)"
],
"execution_count": 0,
"outputs": []
Expand All @@ -867,7 +863,7 @@
"### Detection - Full NAIP Images\n",
"Detect wind turbines in full size NAIP images (~4 miles square) using sliding window of size 300 x 300 pixels over the entire 5978 x 7648 pixel image. \n",
"\n",
"This section provides the individual images containing at least one wind turbine and corresponding bounding box(es), the full NAIP image with all the wind turbines marked, and the latitude and longitude coordinates of all detected wind turbines. "
"This section outputs the individual images containing at least one wind turbine and corresponding bounding box(es), the full NAIP image with all the wind turbines marked, and the latitude and longitude coordinates of all detected wind turbines. "
]
},
{
Expand All @@ -891,63 +887,6 @@
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "6rUOV4iFj5PR",
"colab_type": "code",
"colab": {}
},
"source": [
"def run_inference_for_single_image(image, graph):\n",
" with graph.as_default():\n",
" with tf.Session() as sess:\n",
" # Get handles to input and output tensors\n",
" ops = tf.get_default_graph().get_operations()\n",
" all_tensor_names = {output.name for op in ops for output in op.outputs}\n",
" tensor_dict = {}\n",
" for key in [\n",
" 'num_detections', 'detection_boxes', 'detection_scores',\n",
" 'detection_classes', 'detection_masks'\n",
" ]:\n",
" tensor_name = key + ':0'\n",
" if tensor_name in all_tensor_names:\n",
" tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(\n",
" tensor_name)\n",
" if 'detection_masks' in tensor_dict:\n",
" # The following processing is only for single image\n",
" detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])\n",
" detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])\n",
" # Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.\n",
" real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)\n",
" detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])\n",
" detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])\n",
" detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(\n",
" detection_masks, detection_boxes, image.shape[0], image.shape[1])\n",
" detection_masks_reframed = tf.cast(\n",
" tf.greater(detection_masks_reframed, 0.5), tf.uint8)\n",
" # Follow the convention by adding back the batch dimension\n",
" tensor_dict['detection_masks'] = tf.expand_dims(\n",
" detection_masks_reframed, 0)\n",
" image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')\n",
"\n",
" # Run inference\n",
" output_dict = sess.run(tensor_dict,\n",
" feed_dict={image_tensor: np.expand_dims(image, 0)})\n",
"\n",
" # all outputs are float32 numpy arrays, so convert types as appropriate\n",
" output_dict['num_detections'] = int(output_dict['num_detections'][0])\n",
" output_dict['detection_classes'] = output_dict[\n",
" 'detection_classes'][0].astype(np.uint8)\n",
" output_dict['detection_boxes'] = output_dict['detection_boxes'][0]\n",
" output_dict['detection_scores'] = output_dict['detection_scores'][0]\n",
" if 'detection_masks' in output_dict:\n",
" output_dict['detection_masks'] = output_dict['detection_masks'][0]\n",
" return output_dict"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
Expand Down Expand Up @@ -975,11 +914,9 @@
" width, height = image.size\n",
" ii=0\n",
" for x0 in range(0, width, chipsize): # width\n",
" #ii=ii+1\n",
" ii+=1\n",
" jj=0\n",
" for y0 in range(0, height, chipsize): # height\n",
" #jj=jj+1\n",
" jj+=1\n",
" box = (x0, y0,\n",
" x0+chipsize,\n",
Expand Down Expand Up @@ -1008,8 +945,7 @@
" for kk in range(len(output_dict['detection_scores'][output_dict['detection_scores']>0.5])):\n",
" plt.plot(chipsize*np.mean([BBsWTs[-1-kk][1],BBsWTs[-1-kk][3]]),chipsize*np.mean([[BBsWTs[-1-kk][0],BBsWTs[-1-kk][2]]]),'bo')\n",
" detectedWTs.append([image_path,ii,jj])\n",
" plt.imshow(image_np)\n",
" # plt.savefig('%s_%02d_%02d.jpg' % (image_path.replace('.jpg',''), ii, jj),bbox_inches='tight')"
" plt.imshow(image_np)"
],
"execution_count": 0,
"outputs": []
Expand Down Expand Up @@ -1085,7 +1021,6 @@
" x_plot=chipsize*(detectedWTs[ll][1]-1+centerBBs[ll][0])\n",
" y_plot=chipsize*(detectedWTs[ll][2]-1+centerBBs[ll][1])\n",
" plt.plot(x_plot,y_plot,'ro')\n",
" #plt.legend('Wind Turbines',loc='lower left',numpoints=1)\n",
" plt.imshow(image)\n"
],
"execution_count": 0,
Expand Down Expand Up @@ -1158,122 +1093,6 @@
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "1kvmN35pkiqO",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "zuvNdgN7kiy6",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "5SQ-QPURki6W",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "AuClqbHJhXqg",
"colab_type": "code",
"colab": {}
},
"source": [
"# initialize dictionaries for NAIP image corners\n",
"# y1,x1 are lat,long of upper left corner of image\n",
"# y2,x2 are lat,long of upper right corner of image\n",
"# y3,x3 are lat,long of lower right corner of image\n",
"# y4,x4 are lat,long of lower left corner of image\n",
"x1={}\n",
"y1={}\n",
"x2={}\n",
"y2={}\n",
"x3={}\n",
"y3={}\n",
"x4={}\n",
"y4={}\n",
"for image_path in TEST_IMAGE_PATHS:\n",
" print(image_path)\n",
" with open(image_path.replace('.jpg','_md.html')) as fid:\n",
" lines = fid.readlines()\n",
" #print(lines)\n",
" startline = [x for x in range(len(lines)) if 'Data_Set_G-Polygon_Outer_G-Ring:' in lines[x]]\n",
" print(startline)\n",
"\n",
" print(lines[startline[0]+3])\n",
" print(lines[startline[0]+2])\n",
" print(lines[startline[0]+6])\n",
" print(lines[startline[0]+5])\n",
" print(lines[startline[0]+9])\n",
" print(lines[startline[0]+8])\n",
" print(lines[startline[0]+12])\n",
" print(lines[startline[0]+11])\n",
" \n",
" #print(lines[3048-1])+1\n",
" #print(lines[3047-1])\n",
" #print(lines[3051-1])+4\n",
" #print(lines[3050-1])+3\n",
" #print(lines[3054-1])+7\n",
" #print(lines[3053-1])+6\n",
" #print(lines[3057-1])+10\n",
" #print(lines[3056-1])+9\n",
" \n",
" print('x1=', float(lines[startline[0]+3][28-1:]))\n",
" print('y1=', float(lines[startline[0]+2][27-1:]))\n",
" print('x2=', float(lines[startline[0]+6][28-1:]))\n",
" print('y2=', float(lines[startline[0]+5][27-1:]))\n",
" print('x3=', float(lines[startline[0]+9][28-1:]))\n",
" print('y3=', float(lines[startline[0]+8][27-1:]))\n",
" print('x4=', float(lines[startline[0]+12][28-1:]))\n",
" print('y4=', float(lines[startline[0]+11][27-1:]))\n",
" \n",
" x1[image_path]=float(lines[startline[0]+3][28-1:])\n",
" y1[image_path]=float(lines[startline[0]+2][27-1:])\n",
" x2[image_path]=float(lines[startline[0]+6][28-1:])\n",
" y2[image_path]=float(lines[startline[0]+5][27-1:])\n",
" x3[image_path]=float(lines[startline[0]+9][28-1:])\n",
" y3[image_path]=float(lines[startline[0]+8][27-1:])\n",
" x4[image_path]=float(lines[startline[0]+12][28-1:])\n",
" y4[image_path]=float(lines[startline[0]+11][27-1:])\n",
" \n",
"print(x1)\n",
"print(y1)\n",
"print(x2)\n",
"print(y2)\n",
"print(x3)\n",
"print(y3)\n",
"print(x4)\n",
"print(y4)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
Expand All @@ -1283,7 +1102,9 @@
"source": [
"## Summary\n",
"\n",
"The trained model accurately detects 15 out of 17 wind turbines in the validation image set with high probability. This represents an accuracy of ~90% (88.2%). Higher accuracy would likely be acheived by using a larger set of images (train + test) as well as using a more accurate pre-trained model. Alternative models, including those with higher mAP, can be found at the [TensorFlow Object Detection Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md). Details of the trade-offs between speed, accuracy, and memory for various object detection model architectures (Faster RCNN, SSD, R-FCN) can be found in this [paper](https://arxiv.org/pdf/1611.10012.pdf), which can serve as a good starting point in determining which architecture is best for your application."
"The trained model accurately detects at least 15 out of 17 wind turbines in the validation image set with high probability. This represents an accuracy of at least ~90% (88.2%). Higher accuracy would likely be acheived by using a larger set of images (train + test) as well as using a more accurate pre-trained model. Alternative models, including those with higher mAP, can be found at the [TensorFlow Object Detection Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md). Details of the trade-offs between speed, accuracy, and memory for various object detection model architectures (Faster RCNN, SSD, R-FCN) can be found in this [paper](https://arxiv.org/pdf/1611.10012.pdf), which can serve as a good starting point in determining which architecture is best for your application.\n",
"\n",
"Using the trained model, images encompassing a large area (~16 sq miles) were scanned for wind turbines. Once detected, the position of each wind turbine was plotted on the original full NAIP image and its position (latitude, longitude) was output. The comprehensive pipeline including training, validation, and inference could be applied to many other applications involving detection of objects from aerial or satellite images. "
]
}
]
Expand Down

0 comments on commit ffb0a59

Please sign in to comment.