Skip to content

Commit

Permalink
Merge branch 'lengelen-master'
Browse files Browse the repository at this point in the history
* lengelen-master:
  last touches to the multiplane calibration - the main changes were eventually inside py_bind/calibration.pyx - we allowed a bit more relaxed convergence, that was (rightfully so) failing on multi-parameter optimisation. actually it brings an idea that we shall just run a full cycle of calibrations, change first only positions, then without changing positions, only angles, and so on, including additional parameters which are marked, but not all at once - since optimisation fails - but one by one, in a loop. of course a loop can be double directed by finishing and revisiting it few times.
  that's the right way to compare flags
  all imread are back to skimage.io
  imageio is slower than skimage.io for imread flags failed as it's not True, it's either 0 or 1
  removed obsolete try ... except changed .crd .fix to write only matched points
  fixed the missing cal_points - that appears if the previous Initial guess wasn't pressed
  testing a smaller calibration set to find the reason for wrong .crd and .fix
  fixed old bug that didn't copy man_ori.dat in parameters folder
  inside fine orientation - for each camera, if the flag is on, read and prepare, otheriwse just take whatever is there
  some progress - the Load images now also checks if multi params and then sends it with the raw_orient_true to the Fine Orientation directly
  fixed some old bug with the active params - apparently not always the "last" multiplane folder was the one used in the calibration
  i moved all the multi plane calibration part inside the calibration gui, in the fine_orientation (that's what we're doing in reality) - we assume we have a good initial guess from each plane - we shall anyhow start from a good initial guess by copying one of the planes (central one?) into the multi_plane folder calibration, and not start from nothing -
  removed pyc again smal things in parameters, ptv and calibration_gui
  no message
  Update multiplane

# Conflicts:
#	pyptv/ptv.py
#	pyptv/pyptv_gui.py
  • Loading branch information
alexlib committed Nov 16, 2018
2 parents 87e5d0d + abdf586 commit c67d902
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 187 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
__pycache__/
*.py[cod]
*$py.class
*.pyc

# C extensions
*.so
Expand Down Expand Up @@ -66,3 +67,5 @@ tests/test_cavity/parametersRun1
tests/test_cavity/res
.idea
pyptv/parameters
pyptv/.vscode/c_cpp_properties.json
pyptv/.vscode/launch.json
203 changes: 141 additions & 62 deletions pyptv/calibration_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@
from skimage.color import rgb2gray
import os
import shutil
import re

from optv.imgcoord import image_coordinates
from optv.transforms import convert_arr_metric_to_pixel
from optv.orientation import match_detection_to_ref
from optv.segmentation import target_recognition
from optv.orientation import external_calibration, full_calibration
from optv.calibration import Calibration
from optv.tracking_framebuf import TargetArray


import ptv as ptv
import parameter_gui as pargui
Expand Down Expand Up @@ -272,7 +275,6 @@ def update_image(self, image, is_float):


class CalibrationGUI(HasTraits):
camera = List
status_text = Str("")
ori_img_name = []
ori_img = []
Expand Down Expand Up @@ -304,8 +306,8 @@ class CalibrationGUI(HasTraits):
# Constructor
# ---------------------------------------------------
def __init__(self, active_path):
""" Initialize CalibrationGUI
""" Initialize CalibrationGUI
Inputs:
active_path is the path to the folder of prameters
active_path is a subfolder of a working folder with a
Expand All @@ -327,8 +329,9 @@ def __init__(self, active_path):
with open(os.path.join(self.par_path, 'ptv.par'), 'r') as f:
self.n_cams = int(f.readline())


self.camera = [PlotWindow() for i in xrange(self.n_cams)]
for i in xrange(self.n_cams):
self.camera.append(PlotWindow())
self.camera[i].name = "Camera" + str(i + 1)
self.camera[i].cameraN = i
self.camera[i].py_rclick_delete = ptv.py_rclick_delete
Expand Down Expand Up @@ -407,34 +410,47 @@ def _button_edit_cal_parameters_fired(self):
# at the end of a modification, copy the parameters
par.copy_params_dir(self.par_path, self.active_path)
self.cpar, self.spar, self.vpar, self.track_par, self.tpar, \
self.cals = ptv.py_start_proc_c(self.n_cams)
self.cals, self.epar = ptv.py_start_proc_c(self.n_cams)

def _button_showimg_fired(self):

print("Load Image fired \n")
print("Loading images/parameters \n")

# Initialize what is needed, copy necessary things

print("\n Copying man_ori.dat \n")
if os.path.isfile(os.path.join(self.par_path, 'man_ori.dat')):
shutil.copyfile(os.path.join(self.par_path, 'man_ori.dat'),
os.path.join(self.working_folder, 'man_ori.dat'))
print("\n Copied man_ori.dat \n")

# copy parameters from active to default folder parameters/
par.copy_params_dir(self.active_path, self.par_path)

# read from parameters
self.cpar, self.spar, self.vpar, self.track_par, self.tpar, \
self.cals = ptv.py_start_proc_c(self.n_cams)
self.cals, self.epar = ptv.py_start_proc_c(self.n_cams)

self.tpar.read('parameters/detect_plate.par')

print(self.tpar.get_grey_thresholds())


self.calParams = par.CalOriParams(self.n_cams, self.par_path)
self.calParams.read()

if self.epar.Combine_Flag is True :
print("Combine Flag")
self.MultiParams = par.MultiPlaneParams()
self.MultiParams.read()
for i in range(self.MultiParams.n_planes):
print(self.MultiParams.plane_name[i])

self.pass_raw_orient = True
self.status_text = "Multiplane calibration."

# read calibration images

# read calibration images
self.cal_images = []
for i in range(len(self.camera)):
imname = self.calParams.img_cal_name[i]
Expand Down Expand Up @@ -514,22 +530,17 @@ def _button_file_orient_fired(self):
self.need_reset = 0

man_ori_path = os.path.join(self.working_folder, 'man_ori.dat')
try:
f = open(man_ori_path, 'r')
except IOError:
self.status_text = "Error loading man_ori.dat."
else:
with open(man_ori_path, 'r') as f:
for i in range(self.n_cams):
self.camera[i]._x = []
self.camera[i]._y = []
for j in range(4): # 4 orientation points
line = f.readline().split()
self.camera[i]._x.append(float(line[0]))
self.camera[i]._y.append(float(line[1]))
self.status_text = "man_ori.dat loaded."
f.close()
shutil.copyfile(man_ori_path, os.path.join(
self.par_path, 'man_ori.dat'))

self.status_text = "man_ori.dat loaded."
shutil.copyfile(man_ori_path, os.path.join(self.par_path, 'man_ori.dat'))

# TODO: rewrite using Parameters subclass
man_ori_par_path = os.path.join(self.par_path, 'man_ori.par')
Expand Down Expand Up @@ -588,8 +599,9 @@ def _button_sort_grid_fired(self):
self.reset_show_images()
self.need_reset = 0

self.cal_points = self._read_cal_points()
self.sorted_targs = []

print("_button_sort_grid_fired")


Expand Down Expand Up @@ -702,15 +714,88 @@ def _button_fine_orient_fired(self):

flags = []
for name, op_name in zip(names, op_names):
if op_name is True:
if (op_name == 1):
flags.append(name)

print(flags)

for i_cam in range(self.n_cams):
targs = self.sorted_targs[i_cam]
residuals, targ_ix, err_est = full_calibration(self.cals[i_cam], self.cal_points['pos'], \


for i_cam in range(self.n_cams): # iterate over all cameras

if self.epar.Combine_Flag:

self.status_text = "Multiplane calibration."
""" Performs multiplane calibration, in which for all cameras the
pre-processed planes in multi_plane.par combined.
Overwrites the ori and addpar files of the cameras specified
in cal_ori.par of the multiplane parameter folder
"""

all_known = []
all_detected = []

for i in range(self.MultiParams.n_planes): # combine all single planes

# c = self.calParams.img_ori[i_cam][-9] # Get camera id
c = re.findall('\\d+',self.calParams.img_ori[i_cam])[0] # not all ends with a number

file_known = self.MultiParams.plane_name[i]+c+'.tif.fix'
file_detected = self.MultiParams.plane_name[i]+c+'.tif.crd'

# Load calibration point information from plane i
try:
known = np.loadtxt(file_known)
detected = np.loadtxt(file_detected)
except:
raise IOError("reading {} or {} failed".format(file_known,file_detected))


if np.any(detected == -999):
raise ValueError(("Using undetected points in {} will cause " +
"silliness. Quitting.").format(file_detected))

num_known = len(known)
num_detect = len(detected)

if num_known != num_detect:
raise ValueError("Number of detected points (%d) does not match" +\
" number of known points (%d) for %s, %s" % \
(num_known, num_detect, file_known, file_detected))

if len(all_known) > 0:
detected[:,0] = all_detected[-1][-1,0] + 1 + np.arange(len(detected))

# Append to list of total known and detected points
all_known.append(known)
all_detected.append(detected)


# Make into the format needed for full_calibration.
all_known = np.vstack(all_known)[:,1:]
all_detected = np.vstack(all_detected)

# this is the main difference in the multiplane mode
# that we fill the targs and cal_points by the
# combined information

targs = TargetArray(len(all_detected))
for tix in xrange(len(all_detected)):
targ = targs[tix]
det = all_detected[tix]

targ.set_pnr(tix)
targ.set_pos(det[1:])

self.cal_points = np.empty((all_known.shape[0],)).astype(dtype=[('id', 'i4'), ('pos', '3f8')])
self.cal_points['pos'] = all_known
else:
targs = self.sorted_targs[i_cam]

try:
residuals, targ_ix, err_est = full_calibration(self.cals[i_cam], self.cal_points['pos'], \
targs, self.cpar, flags)
except:
raise ValueError("full calibration failed\n")
# save the results
self._write_ori(i_cam)

Expand Down Expand Up @@ -741,12 +826,45 @@ def _button_fine_orient_fired(self):
def _write_ori(self, i_cam):
""" Writes ORI and ADDPAR files for a single calibration result
"""

ori = self.calParams.img_ori[i_cam]
addpar = ori.replace('ori', 'addpar')
print("Saving:", ori, addpar)
self.cals[i_cam].write(ori, addpar)
if self.epar.Examine_Flag and not self.epar.Combine_Flag:
self.save_point_sets(i_cam)

def save_point_sets(self, i_cam):
"""
Saves detected and known calibration points in crd and fix format, respectively.
These files are needed for multiplane calibration.
"""

ori = self.calParams.img_ori[i_cam]
txt_detected = ori.replace('ori', 'crd')
txt_matched = ori.replace('ori', 'fix')


detected, known = [],[]
targs = self.sorted_targs[i_cam]
for i,t in enumerate(targs):
if t.pnr() != -999:
detected.append(t.pos())
known.append(self.cal_points['pos'][i])
nums = np.arange(len(detected))
# for pnr in nums:
# print(targs[pnr].pnr())
# print(targs[pnr].pos())
# detected[pnr] = targs[pnr].pos()

detected = np.hstack((nums[:,None], np.array(detected)))
known = np.hstack((nums[:,None], np.array(known)))

np.savetxt(txt_detected, detected, fmt="%9.5f")
np.savetxt(txt_matched, known, fmt="%10.5f")

def _button_orient_part_fired(self):

self.backup_ori_files()
ptv.py_calibration(10)
x1, y1, x2, y2 = [], [], [], []
Expand All @@ -765,45 +883,6 @@ def _button_orient_part_fired(self):

self.status_text = "Orientation with particles finished."

# def _button_orient_dumbbell_fired(self):
# print "Starting orientation from dumbbell"
# self.backup_ori_files()
# ptv.py_ptv_set_dumbbell(1)
# n_camera = len(self.camera)
# print ("Starting sequence action")
# seq_first = self.exp1.active_params.m_params.Seq_First
# seq_last = self.exp1.active_params.m_params.Seq_Last
# print seq_first, seq_last
# base_name = []
# for i in range(n_camera):
# exec (
# "base_name.append(self.exp1.active_params.m_params.Basename_%d_Seq)" % (i + 1))
# print base_name[i]
# ptv.py_sequence_init(1)
# stepshake = ptv.py_get_from_sequence_init()
# if not stepshake:
# stepshake = 1
#
# temp_img = np.array([], dtype=np.ubyte)
# for i in range(seq_first, seq_last + 1, stepshake):
# seq_ch = "%04d" % i
# print seq_ch
# for j in range(n_camera):
# print ("j %d" % j)
# img_name = base_name[j] + seq_ch
# print ("Setting image: ", img_name)
# try:
# temp_img = imread(img_name).astype(np.ubyte)
# except:
# print "Error reading file"
# ptv.py_set_img(temp_img, j)
#
# ptv.py_sequence_loop(1, i)
#
# print "Orientation from dumbbell - sequence finished"
# ptv.py_calibration(12)
# ptv.py_ptv_set_dumbbell(1)
# print "Orientation from dumbbell finished"

def _button_restore_orient_fired(self):
self.restore_ori_files()
Expand Down
2 changes: 1 addition & 1 deletion pyptv/ext_sequence_denis.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import random

import numpy as np
from scipy.misc import imread
from skimage.io import imread


class Sequence():
Expand Down
Loading

0 comments on commit c67d902

Please sign in to comment.