Skip to content
Snippets Groups Projects
Commit bbddb10f authored by Anders Langlie's avatar Anders Langlie
Browse files

cleaned up code and commented

parent 0ea312e2
No related branches found
No related tags found
1 merge request!52Resolve "Document algorithm functions and classes"
class SalamanderImage():
descriptors = []
filename = ''
from cv2 import cv2
import numpy as np
import algorithm.dsift as dsift
def __init__(self, filename):
self.filename
class SalamanderImage:
descriptors = []
filename = ''
def __init__(self, filename):
self.filename = filename
self.descriptors = self.calculate_descriptors()
def calculate_descriptors(self):
"""
Calculates the descriptors if the member image
Returns: The calculated descriptors
"""
image = cv2.imdecode(np.fromfile(self.filename, dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
if image is None:
raise FileNotFoundError("Cannot find image file " + self.filename)
return dsift.compute_descriptors(image)
import os
from cv2 import cv2
from algorithm.imageprocessing import create_salamander_image
import glob
min_good_match = 15
match_dist = 0.75
from algorithm.SalamanderImage import SalamanderImage
def match_single_image(input_salamander, match_salamander):
"""
Compares two SalamanderImages and determines if they are similar enough to be a match
Args:
input_salamander: SalamanderImage of input salamander
match_salamander: SalamanderImage of salamander from the database
Returns:
Boolean value indicating if the comparison was a match and the number of hits gotten in the comparison
"""
min_good_match = 15
match_dist = 0.75
match = cv2.BFMatcher().knnMatch(input_salamander.descriptors, match_salamander.descriptors, k=2)
goodmatch = []
......@@ -20,16 +31,28 @@ def match_single_image(input_salamander, match_salamander):
def match_file_structure(input_image: str, match_directory: str):
"""
Loops through a given directory of salamanders represented by folders containing their images, and finds the best
match (if any) based on an input image
Args:
input_image: SalamanderImage of input salamander
match_directory: Path of directory to looped through
Returns:
The ID of the best matched salamander or None if no match is found
"""
best_match = -1
match_count = 0
# check if input path is valid:
if os.path.isfile(input_image):
input_salamander = create_salamander_image(input_image)
input_salamander = SalamanderImage(input_image)
for folder in os.listdir(match_directory):
name_list = glob.glob(os.path.join(match_directory, folder, "*_str.*"))
for filename in name_list:
res, num_matches = match_single_image(input_salamander, create_salamander_image(filename))
res, num_matches = match_single_image(input_salamander, SalamanderImage(filename))
if res and num_matches > match_count:
match_count = num_matches
best_match = int(folder)
......
......@@ -7,6 +7,15 @@ sift = cv2.SIFT_create()
def compute_descriptors(image):
dense = sift.compute(image,kp)
"""
Computes the descriptors of an incoming image
Args:
image: Image from openCV
Returns:
Descriptors of image
"""
dense = sift.compute(image, kp)
des = dense[1]
return des
from cv2 import cv2
import numpy as np
from algorithm.SalamanderImage import SalamanderImage
import algorithm.dsift as dsift
import algorithm.segmentation as segmentation
def create_salamander_image(filename: str):
salamander_image = SalamanderImage(filename)
salamander_image.filename = filename
salamander_image.descriptors = get_descriptors(filename)
return salamander_image
def get_descriptors(filename: str):
image = get_straightened_image(filename)
return calculate_descriptors(image)
# Reads, straightens, resizes the image and returns it
def get_straightened_image(filename: str):
straightened_filename = filename # [0:-4] + '_str.jpg'
image = get_image(straightened_filename)
return image
# Should return a binary image (numpy ndarray) with 1 for "Part of salamander"
# and 0 for "Not part of the salamander".
def get_segmented_image(filename: str):
image = get_image(filename)
return segmentation.get_salamander_mask(image)
def get_image(filename):
img = cv2.imdecode(np.fromfile(filename, dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
if img is None:
raise FileNotFoundError("Cannot find image file " + filename)
return img
# Calculates descriptors from preprocessed image
def calculate_descriptors(image):
return dsift.compute_descriptors(image)
......@@ -21,7 +21,6 @@ def run_prediction_dlc(config: str, image: np.ndarray, shuffle: int = 1,
if gputouse is not None: # gpu selection
os.environ['CUDA_VISIBLE_DEVICES'] = str(gputouse)
# tf.compat.v1.reset_default_graph()
reset_default_graph()
# record cwd to return to this directory in the end:
......@@ -30,7 +29,6 @@ def run_prediction_dlc(config: str, image: np.ndarray, shuffle: int = 1,
model_folder = os.path.join(cfg["project_path"],
str(auxiliaryfunctions.GetModelFolder(train_fraction, shuffle, cfg)))
path_test_config = Path(model_folder) / 'test' / 'pose_cfg.yaml'
# print(path_test_config)
try:
dlc_cfg = load_config(str(path_test_config))
except FileNotFoundError:
......@@ -58,24 +56,17 @@ def run_prediction_dlc(config: str, image: np.ndarray, shuffle: int = 1,
increasing_indices = np.argsort([int(m.split('-')[1]) for m in snapshots])
snapshots = snapshots[increasing_indices]
# print("Using %s" % snapshots[snapshot_index], "for model", model_folder)
##################################################
# Load and setup CNN part detector
##################################################
# Check if data already was generated:
dlc_cfg['init_weights'] = os.path.join(model_folder, 'train', snapshots[snapshot_index])
trainingsiterations = (dlc_cfg['init_weights'].split(os.sep)[-1]).split('-')[-1]
# Update batchsize (based on parameters in config.yaml)
dlc_cfg['batch_size'] = 1
# Name for scorer:
# DLCscorer, DLCscorerlegacy = auxiliaryfunctions.GetScorerName(cfg,shuffle,trainFraction,trainingsiterations=trainingsiterations)
# return tensorflow session, input and outbut (whatever those are):
sess, inputs, outputs = predict.setup_pose_prediction(dlc_cfg)
# sess, inputs, outputs = predict.setup_pose_prediction(dlc_cfg)
# update number of outputs and adjust pandas indices
dlc_cfg['num_outputs'] = cfg.get('num_outputs', 1)
......@@ -86,26 +77,12 @@ def run_prediction_dlc(config: str, image: np.ndarray, shuffle: int = 1,
##################################################
# Loading the images
##################################################
# Predicting data:
# print("session: ", sess)
# PredictedData,nframes,nx,ny=get_poses_deeplabcut_model(dlc_cfg, sess, inputs, outputs,image)
ny, nx, nc = np.shape(image)
nframes = 1
# print("Frame dimensions: ", nx,ny)
PredictedData = np.zeros((nframes, dlc_cfg['num_outputs'] * 3 * len(dlc_cfg['all_joints_names'])))
# change from int:
frame = img_as_ubyte(image)
pose = predict.getpose(frame, dlc_cfg, sess, inputs, outputs)
PredictedData[0, :] = pose.flatten()
stop = time.time()
# print("PredictedData done:\n")
# closing the session:
# device = cuda.get_current_device()
# device.reset()
# tf.Graph.reset_default_graph()
return PredictedData[0], nframes, nx, ny
from cv2 import cv2
import numpy as np
def get_salamander_mask(image):
ret, threshold = cv2.threshold(image, np.mean(image) - 40, 255, 0)
i, contours, hierarchy = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
largest_area, largest_contour_index = find_biggest_contour(contours, image.size)
cv2.drawContours(image, contours[largest_contour_index], -1, (0, 0, 255), 3)
mask = np.zeros(image.shape)
cv2.fillPoly(mask, pts=[contours[largest_contour_index]], color=(255, 255, 255))
return mask
def find_biggest_contour(contours, imsize):
largest_area = 0
largest_contour_index = -1
i = 0
total_contours = len(contours)
while i < total_contours:
area = cv2.contourArea(contours[i])
if largest_area < area < imsize * 0.9:
largest_area = area
largest_contour_index = i
i += 1
return largest_area, largest_contour_index
......@@ -169,11 +169,14 @@ def straighten(image):
def generate_map_from_bellycurve(curve, width=STRAIGTHENED_IMAGE_WIDTH):
"""
Generates a map that can be passed to cv2.remap to extract the belly pattern
"""
# salamander_length = np.linalg.norm(curve[len(curve) - 1] - curve[0])
Args:
curve: Interpolated curve along the spine
width: Width of the abdominal pattern
Returns: Map generated from the curve
"""
# salamander_width = salamander_length * STRAIGHTENED_IMAGE_ASPECT_RATIO
salamander_width = width + SHOULDER_ESTIMATION_BUFFER
gradient = np.gradient(curve, axis=0)
......@@ -200,10 +203,16 @@ def get_smooth_curve(points, num_points):
Takes in an array of 2-D points and returns a new set of points
with numpoints elements where the missing points are interpolated
using cubic interpolation
Args:
points:
num_points:
Returns: Interpolated points
"""
# Calculate distance between all the points
distance = np.sqrt(np.sum(np.diff(points, axis=0) ** 2, axis=1))
# print("distance, ", distance.shape)
# Accumulate distance to use as parameter
accumulated_distance = np.cumsum(distance)
......@@ -223,7 +232,14 @@ def get_smooth_curve(points, num_points):
def halfway_between(point1, point2):
"""
halfway_between() calculates a point between two points:
halfway_between() calculates a point between two points
Args:
point1:
point2:
Returns: A point between the two provided points
"""
vec = [(point2[0] - point1[0]) / 2, (point2[1] - point1[1]) / 2]
return [point1[0] + vec[0], point1[1] + vec[1]]
......@@ -10,7 +10,8 @@ import glob
from shutil import move
from path_constants import _ACCESS_DATABASE
from image_encoder.image_encoder import *
import cv2
from cv2 import cv2
import numpy as np
"""
Endpoint for editing salamanders.
......@@ -43,7 +44,10 @@ class EditSalamander(Resource):
basename = os.path.basename(path)
if basename.__contains__(str(image_id)):
image = cv2.imread(path)
image = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
if image is None:
raise FileNotFoundError("Cannot find image file " + path)
if not basename.__contains__("str"): # Scale only original to set size
height, width, _ = image.shape
......
......@@ -2,7 +2,7 @@ from flask import request, jsonify
from flask_restful import Resource
from flask_jwt_extended import get_jwt_identity, jwt_required
from algorithm.straighten_with_dlc import straighten
import cv2
from cv2 import cv2
import os
from api import limiter
from image_encoder.image_encoder import *
......
......@@ -5,7 +5,8 @@ from api import db, limiter
from api.models.dbmodels import Location, User, Salamander
import os
import glob
import cv2
import numpy as np
from cv2 import cv2
from image_encoder.image_encoder import *
from path_constants import _ACCESS_DATABASE
......@@ -33,8 +34,10 @@ class SalamanderEndpoint(Resource):
list_of_paths = glob.glob(os.path.join(path_to_salamander_images, '*.*'))
for path in list_of_paths:
if not path.__contains__("_str"):
image = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
image = cv2.imread(path)
if image is None:
raise FileNotFoundError("Cannot find image file " + path)
# scaling to set size
height, width, _ = image.shape
......
from api import app
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')
\ No newline at end of file
app.run(debug=True, host='0.0.0.0')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment