Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Added GUI for saturation, brightness, hsv, and update doc for test_pf #68

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
689cf5c
control for 1 frame
Jan 29, 2023
dd8f371
controller for all frames
NLmeng Feb 4, 2023
bd90af0
real time toggle
NLmeng Feb 4, 2023
65f6e99
forcing me to save
abhigyandabla Feb 5, 2023
5d4b2a7
Merge branch 'lymeng/controller' of https://github.com/UBCAgroBot/Nav…
abhigyandabla Feb 5, 2023
555d0f0
Added brightness and saturation toggles to window
abhigyandabla Feb 5, 2023
8cc1051
real time toggle for brightness and saturation
NLmeng Feb 11, 2023
8b7377a
real time toggle for brightness and saturation
NLmeng Feb 11, 2023
fc550cd
created better GUI with tkinter
NLmeng Feb 12, 2023
54e4e36
configure to support all algorithm
NLmeng Feb 13, 2023
45bdc62
update doc, minor change to gui and pre_process
NLmeng Feb 13, 2023
42c493d
pass in filtered frame to algorithm with gui
NLmeng Feb 18, 2023
3eebc25
minor changes
NLmeng Feb 18, 2023
f8d4529
connect hsv from gui to algorithms, and added upper and lower hsv to gui
NLmeng Mar 2, 2023
7283f94
alert when UPPER hsv < LOWER hsv and vice versa
NLmeng Mar 2, 2023
f586e9d
small addition to readme
NLmeng Mar 3, 2023
e10ec73
conflicts
NLmeng Mar 3, 2023
a4a6809
autopep8
NLmeng Mar 3, 2023
3385cdd
added Pillow dependency
NLmeng Mar 3, 2023
b43fbfa
show the whole frame
NLmeng Mar 3, 2023
5c90f93
added scrollbar
NLmeng Mar 3, 2023
b7e12ef
fixed dimension problem, expand smoother
NLmeng Mar 3, 2023
47b84ef
fix bug with lowerhsv and apply precommit
NLmeng Mar 4, 2023
e188fb5
Merge branch 'main' into abhi/hsvsliders
NLmeng Mar 4, 2023
c3968ce
revert
NLmeng Mar 4, 2023
0c64b53
reverted some commits
NLmeng Mar 4, 2023
bc467bb
Revert "fix bug with lowerhsv and apply precommit"
NLmeng Mar 4, 2023
d1b4970
recommit 'fixed dimension problem, expand smoother, fix bug with lowe…
NLmeng Mar 4, 2023
be8fd0d
add masked
NLmeng Mar 4, 2023
be7c5d5
retrieve mask from every algorithm and display
NLmeng Mar 11, 2023
c00d0f4
added sys and path
NLmeng Mar 18, 2023
3e926ea
seesaw version 2
zoeyzhao57 Mar 11, 2023
f167676
seesaw version 2 update
zoeyzhao57 Mar 11, 2023
e7d2c56
seesaw version 2 update
zoeyzhao57 Mar 18, 2023
0e3c0dd
autopep8 action fixes (#72)
github-actions[bot] Mar 11, 2023
3881924
seesaw version 2 update
zoeyzhao57 Mar 25, 2023
65ec752
add seesaw2 to gui
NLmeng Apr 1, 2023
7fe691a
changed hsv to sliders and add color canvas for each
NLmeng Apr 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 42 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,54 @@

> For AgroBot one of the main concern is the robot's navigation. The robot must autonomously navigate the crop rows and for this task we are taking a computer vision approach. The goal of this script is to efficiently detect crop rows on a video.

## Getting started
# Getting started

### How to install
# How to install

- install [python 3.9](https://www.python.org/downloads/release/python-390/)
- install[python 3.9](https: // www.python.org/downloads/release/python-390/)
- `git clone` this repository
- run `pip install pipenv`
- `cd` into project root
- run `pipenv install` to install project dependencies
- run `pipenv shell` to launch virtual environment

### Scripts
# Scripts

`test_algorithms.py:`
`test_algorithms.py: `

- runs any of the 4 algorithms against any video
- arguments :
- `-a/--alg` : name of algorithm
- `hough`, `center_row`, `mini_contour` or `scanning`
- `-v/--vid` : name of video
- video has to be stored in `./videos/`
- video configuration has to be stored as a `yaml` at `./config/video/`
- `-s/--show` : process drawings and show frame
- example : `python test_algorithms.py -a center_row -v crop`
- arguments:
- `-a/--alg`: name of algorithm
- `hough`, `center_row`, `mini_contour` or `scanning`
- `-v/--vid`: name of video
- video has to be stored in `./videos/`
- video configuration has to be stored as a `yaml` at `./config/video/`
- `-s/--show`: process drawings and show frame
- example: `python test_algorithms.py - a center_row - v crop`

`create_dataset.py:`
`create_dataset.py: `

- aids in data extraction from any video
- arguments :
- `-v/--vid` : name of video
- video has to be stored in `./videos/`
- `-i/--interval (optional, default = 30)`: interval between keyframes
- `-o/--overwrite (optional, default = False)` : flag to indicate that you wish to overwrite files at `./extract/vid`
- example : `python create_dataset.py -v sim` or `python create_dataset.py -v crop -i 60 -o`

`test_pf.py:`

- runs performance tests on any of the algorithms against any video
- reports `framerate`, `time-to-finish`, `vanishing point uptime`, `avg time to process frame`
- arguments :
- `-a/--alg` : name of algorithm
- `hough`, `center_row`, `mini_contour`, `mini_contour_downward`, `scanning`, `check_row_end` or `center_down`
- `-v/--vid` : name of video
- video has to be stored in `./videos/`
- video configuration has to be stored as a `yaml` at `./config/video/`
- `-s/--show` : process drawings and show frame
- example : `python test_pf.py -a center_row -v farm4`

### Commands to Start World in Gazebo
- arguments:
- `-v/--vid`: name of video
- video has to be stored in `./videos/`
- `-i/--interval(optional, default=30)`: interval between keyframes
- `-o/--overwrite(optional, default=False)`: flag to indicate that you wish to overwrite files at `./extract/vid`
- example: `python create_dataset.py - v sim` or `python create_dataset.py - v crop - i 60 - o`

`test_pf.py: `
- runs performance tests on any of the algorithms against any video with an optional GUI
- reports `framerate`, `time-to-finish`, `vanishing point uptime`, `avg time to process frame`
- arguments:
- `-a/--alg`: name of algorithm
- `hough`, `center_row`, `mini_contour`, `mini_contour_downward`, `scanning`, `seesaw`, or `check_row_end`
- `-v/--vid`: name of video
- video has to be stored in `./videos/`
- video configuration has to be stored as a `yaml` at `./config/video/`
- `-s/--show`: creates a GUI that shows the frame, allow filter, toggle between views, adjust saturation, brightness, upper, and lower HSV
- example : `python test_pf.py - a center_row - v crop - s`

# Commands to Start World in Gazebo

Run the following Commands the first time:

Expand All @@ -60,21 +59,21 @@ Run the following Commands the first time:
Run the following commands to open the world:

- Go to agrobot_ws/src folder
- Run bash script (start_corn_fields.sh or start_wheat_fields.sh)
- Run bash script(start_corn_fields.sh or start_wheat_fields.sh)

To run PID, open a new terminal:

- Run run_controller bash script

To reset the position of the robot:

- Edit > Reset model poses (to reset the position of your robot to the start position)
- Edit > Reset model poses(to reset the position of your robot to the start position)

## Demo
# Demo

![](/readme_files/demo_vid.mp4)

### Colour Filtering
# Colour Filtering

To accomplish this task, we need to first denoise the image. In particular, since we know we are looking for crops which
are green in colour, we can filter based on colour. We convert our image to HSV format and define upper and lower bound
Expand All @@ -90,9 +89,9 @@ By using bitwise and operator we see that this mask does correspond to the green

![crop bitwise](/readme_files/greenregions.png)

### Denoising and Smoothing
# Denoising and Smoothing

Next, we need to denoise the resulting mask (which is a binary image containing the crop rows). To do this, we perform
Next, we need to denoise the resulting mask(which is a binary image containing the crop rows). To do this, we perform
gaussian blurring following by multiple iterations of dilation. Here is the resulting mask after dilation:

![denoising](/readme_files/denoising.png)
Expand All @@ -102,7 +101,7 @@ and also we want rows that are far from the camera to be merged into one. This i
our navigation system and by merging them, we can avoid detecting them in our edge and line detection in subsequent
steps.

### Line Detection
# Line Detection

Although, the mask image is a binary image and it can be used directly with Hough transform, the large number of points
in the image lead to noisy and slow computation. Hence, Canny edge detection was used to first decrease the number of
Expand All @@ -116,7 +115,7 @@ image shows the resulting lines we detected.

![Houghlines](/readme_files/Houghlines.png)

### How does this fit in with the rest of the system?
# How does this fit in with the rest of the system?

We are currently using these lines and calculating their intersection which occurs at vanishing point. Then we are using
a PID controller to minimimize the distance of this vanishing point from the center of our frame. Using this method, we
Expand Down
13 changes: 12 additions & 1 deletion algorithms/CenterRowAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import cv2 as cv
import numpy as np
from algorithms.Algorithm import Algorithm

from algorithms.Algorithm import Algorithm
from algorithms.utils import Lines


Expand All @@ -18,6 +18,7 @@ def __init__(self, config):
# masking range for green
self.LOW_GREEN = np.array(config.lower_hsv_threshold)
self.HIGH_GREEN = np.array(config.upper_hsv_threshold)
# print(self.LOW_GREEN, self.HIGH_GREEN)

# filtering parameters
self.averaging_kernel_size = config.averaging_kernel_size
Expand All @@ -44,6 +45,16 @@ def __init__(self, config):
self.center = None
self.center_angle = 0

def get_extra_content(self, frame, show):
item1, item2 = self.process_frame(frame, show)
return item1, item2

def update_lower_hsv(self, next):
self.LOW_GREEN = np.array(next)

def update_upper_hsv(self, next):
self.HIGH_GREEN = np.array(next)

def process_frame(self, frame, show):
"""Uses contouring to create contours around each crop row and uses these contours to find centroid lines,
row vanishing point, a center contour and the angle between the center contour and vanishing point\n
Expand Down
10 changes: 10 additions & 0 deletions algorithms/CheckRowEnd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ def __init__(self, config):
# Percentage of empty rows required to register as row end
self.percentage_of_empty_rows = config.percentage_of_empty_rows

def get_extra_content(self, frame, show):
item1, item2 = self.process_frame(frame, show)
return item1, item2

def update_lower_hsv(self, next):
self.LOW_GREEN = np.array(next)

def update_upper_hsv(self, next):
self.HIGH_GREEN = np.array(next)

def process_frame(self, frame, show):
"""Averages values in each row in a mask of the frame. If the number of rows with an average value
of zero is greater than req_rows_empty, then frame is row end\n
Expand Down
10 changes: 10 additions & 0 deletions algorithms/HoughAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ def __init__(self, config):
# resize factor
self.RESIZE_FACTOR = config.resize_factor

def get_extra_content(self, frame, show):
item1, item2 = self.process_frame(frame, show)
return item1, item2

def update_lower_hsv(self, next):
self.LOW_GREEN = np.array(next)

def update_upper_hsv(self, next):
self.HIGH_GREEN = np.array(next)

# processFrame function that is called to process a frame of a video
# takes in frame mat object obtained from cv2 video.read()
def process_frame(self, frame, show=True):
Expand Down
22 changes: 17 additions & 5 deletions algorithms/MiniContoursAlgorithm.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import cv2
import numpy as np
import time
import math
import operator
import sys
import math
from algorithms.utils import Lines
import time

import cv2
import numpy as np

from algorithms.Algorithm import Algorithm
from algorithms.utils import Lines


class MiniContoursAlgorithm(Algorithm):
Expand Down Expand Up @@ -199,6 +201,16 @@ def get_center_hough_lines(

return frame, lines, point_lines

def get_extra_content(self, frame, show):
item1, item2 = self.process_frame(frame, show)
return item1, item2

def update_lower_hsv(self, next):
self.LOW_GREEN = np.array(next)

def update_upper_hsv(self, next):
self.HIGH_GREEN = np.array(next)

def process_frame(self, original_frame, num_strips=60, show=False):

# original_frame: BGR frame
Expand Down
10 changes: 10 additions & 0 deletions algorithms/MiniContoursDownwards.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ def get_best_fit_line(self, frame, show, num_strips=60, dist_type=cv2.DIST_L2, p

return frame, line

def get_extra_content(self, frame, show):
item1, item2 = self.process_frame(frame, show)
return item1, item2

def update_lower_hsv(self, next):
self.LOW_GREEN = np.array(next)

def update_upper_hsv(self, next):
self.HIGH_GREEN = np.array(next)

def process_frame(self, original_frame, num_strips=60, show=False):
"""""
parameters:
Expand Down
10 changes: 10 additions & 0 deletions algorithms/ScanningAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ def create_line(self, start_x, start_y, end_x, end_y):

return line

def get_extra_content(self, frame, show):
item1, item2 = self.process_frame(frame, show)
return item1, item2

def update_lower_hsv(self, next):
self.LOW_GREEN = np.array(next)

def update_upper_hsv(self, next):
self.HIGH_GREEN = np.array(next)

def process_frame(self, frame, show):

hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
Expand Down
10 changes: 10 additions & 0 deletions algorithms/SeesawAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ def __init__(self, config):
self.HEIGHT = int(config.frame_length)
self.WIDTH = int(config.frame_width)

def get_extra_content(self, frame, show):
item1, item2 = self.process_frame(frame, show)
return item1, item2

def update_lower_hsv(self, next):
self.LOW_GREEN = np.array(next)

def update_upper_hsv(self, next):
self.HIGH_GREEN = np.array(next)

def process_frame(self, frame, show):

black_frame, points, both_points = self.plot_points(frame)
Expand Down
Loading