From d029efc6797ac47c61b125dcd9e2c6007af3c83f Mon Sep 17 00:00:00 2001 From: Harrison Edwards Date: Tue, 6 Feb 2018 18:55:03 -0500 Subject: [PATCH] added a directory organizer and improved autofocus --- LCL_run.py | 8 +- __pycache__/autofocus.cpython-36.pyc | Bin 6315 -> 5332 bytes autofocus.py | 162 +++++++++------------------ directory_organizer.py | 47 ++++++++ 4 files changed, 106 insertions(+), 111 deletions(-) create mode 100644 directory_organizer.py diff --git a/LCL_run.py b/LCL_run.py index ce444f5..3e27fc3 100644 --- a/LCL_run.py +++ b/LCL_run.py @@ -57,7 +57,11 @@ class ShowVideo(QtCore.QObject): # print(cv2.Laplacian(image, cv2.CV_64F).var()) self.draw_reticle(image) if self.noise_removal == True: + print('denoising...') + self.camera.set(3,1024) + self.camera.set(4,822) image = cv2.fastNlMeansDenoisingColored(image,None,3,7,7) + print('done denoising') color_swapped_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) height, width, _ = color_swapped_image.shape qt_image = QtGui.QImage(color_swapped_image.data, @@ -192,7 +196,7 @@ class main_window(QMainWindow): self.vid.noise_removal = True else: print('unchecked!') - self.vid.noise_removal = True + self.vid.noise_removal = False def setup_combobox(self): magnifications = [ @@ -252,6 +256,8 @@ class main_window(QMainWindow): positions = ituple[0] variances = ituple[1] plt.plot(variances) + plt.xlabel('position') + plt.ylabel('variance of laplacian') plt.show() # def on_key_press(symbol, modifiers): diff --git a/__pycache__/autofocus.cpython-36.pyc b/__pycache__/autofocus.cpython-36.pyc index cbe61b5fbf69d3601c30919e1bcd039111439a23..a5fb1e813d33c4395d485ebffc9f98c4d8316f51 100644 GIT binary patch literal 5332 zcmbVQTaO$^74F;IdM-P&_gy<=k`TxQSm8|q$cjkJIu1ec#*R%KwKi&Xx_WoJ-P1j; zu37Jnd*ERlB`-)kA#OqlAtZhR5|6wh!6Pl6-~~(kg1m(9RL}IzZft?*QJ<eM;&QnP9P`L&Vtw`E27r!w~#=)aCP`5gdLm>Md#^H!azkH2#n!F59Bo()+2%7#VYA<|T9T$5F7(@0drIH27T;7@g;gIatm>J; z(nPnGy%kowtMT7>%M-;~^;Uzmi2{1uf{LUu2u?0`N;8D~4h%L*A#dx-%5pGv`jH&j*}2nYKKEQwL>J^B<-)ApKlI&0nnBY~XGPut zRCeT@&eFo3%uEgJibLAWrXCygJ_GQvjg|HB}~B zprz_WRTZI6lvJ^eR0+s{5-0m*G7=m}$7qFN+^(_`U`?20(jQ?JyDsq!N#A5uNl%n5 ziCK`aEn!E(MG2QAT$XS}!c_^^BwUwpgVlan$4Z;WFW`GKxG+(!Dj#g_X=81yi;K(* zo=UY8yiX*T_x^YXQb2+)06tB8$geKoGmZc*R$KUq?g+x~9@Md2!xaqSW5rKei8 z0gqiTNxb9{BTRkNbcdYdkaR=8?~75xjU&P15Jq9%sL_YB%uIo=Im3)v+)G?1glQaC z#C)^>_c`!HL2fl1*Y!e=%ab;$deH$~k-au*(lSS07`whWxjbqzM>ud7;qfCU9Cc{R zv#9ce@#XG=aqrozlne(R=M}J?Rc+gkd|}&G|tgvb?o9r~2t*Zt^*JQQ)1e>=y;cN_HY=4!nrwQ6;Mxh)l2 z5YaAI=2UB$Kul$`me9ZM9KSbJZ_WnIm}l8qBq~2TgRA5Gi(z6j-xXQO7hXT%fzj^o{<@e7w%`} zfkUpDsdqE=2(h|m+ir*uXWPG5KHc8Ay!U;Cy=3qDyI=dxJMUlGyXqx(MLgJhd*^LC ziTA~Q%-$;kieGHy#0zX(JQo}%6gz_;)wGQ4S{ z=jL~Pf~x;_CKj>slnMR?+Kv$CSy%<`RlJX7;R%K-qA{^ex{!KUM<=ByidbbRfy&fx zLP<6*RA@!peMAAOr@`guB=QCMB{jsm=%3>&YajW{o<=b{31jg(h!S~Q!)Bw4XEb$= z)TOQHp|-FSNsssm&g2aNiv^TSz+O6UV$7=Jw9GtM>I#M=3!Z1K0lFf1TmwPQ7MyCd zKF`)X+2d8VRj^cCRA6eZkIO1BQgsb^1?5Uok^Wy07keeib4F2WK1gJ3AZBM*Mun^c z%-PVA3#aA6J;o`r4Z7QH5!>7gWj0WV`#lnu;-x|-N*g^tFYps*J>DQMJYITv0ZK#Z z%qZk8?eeEV@Bh67K-Zps{O`{`>lwKkT99!r0Q2WS%D)KkBopH53vC2E#13`~bf+?% zGvYkq|1E}Ih+&);V=4jvGI9Lh*ltR0KE&lke7}E=?~Qp|oS{6!cyVAaV}5=h<~;6< z_vI;*Fqj@7RSL>TPh>(RJrSbN`SROfebkYO8>N>I#>g;{8TKmDG|~!l($Vf5MTo+m z1$csakXyzBn?(2kL`fAu`Wqdwm3b)(y2ndM9`Jbyfzj)zB<4<)zAI0a|EC&w%6%$l z{CTXvTL4esw4U7eqXV1MCFz3fG!(3z;d72^7M!rvY4H3NKA1X2_zVz4C+eO~iQ$;i zST$Aa^8Dvx)W>LPTpm}_N}y3ylvYw>O&M27vcNb{(&~PGinO$J*Wic1mx40VOGJ@q zIW46cu;~gsi+1uCh70};7%TSj9vfNh}yRge*QCh{_tAQ%-YiI zHWGWD>wtd=f@Br$0h4&y#o`7*o?st2+;<|^vlIUya>C5;kUZsHLVC_90Kb)7kB^|z z%n*Lx!{r%z-k?{TUZqmcR&BP>C98(?QYN04EOUlUfS&cYPbs$ND7LKy5ep|QSW3!Qlgf|giF;Vu(Zw5h!SM-m-Y2^LdSK(xA863f8~ zM&S@?by)_1aSb%pv^LQ&-eI+1F<&Ls)7r+giaDn0rI6#tDmMhmcxKX?_x^Q9nV*qr z`#P?-dLC46`*d&n3T_(z7tojgSKR!g?#$R!Egt#@hh8GOGfPwHkhR?~M$vP6J&#_L zRmjxwXddEI?8;(@QMf9Wd@w$B>~-FTwXC{>zYtDrCpn2+>DaliejQ_+%$YT(3CbHs zNM93qt!8CR@**aanoM_(wsA)f;G$0WCU=-md2V^O?z(~yWW8Qw6Qv$8?!b}QCGbqAGQA0v^wVGBw1-F{BT;>bx_p}AaLk^ zh~kKPsJQZ0AA~3Z>A#j&a_!ZG{F@8`m{VbrEy%I0o8pe-E|Gq3E%%3^@TblX+AXS` z^D?>=4g09TuF&Ml&HV2hDJ`c=Ia8fnr-lAZ`edzl{U0Bvi3boTXm_Uei$5 P@ix?|zW76>OuqFWfWH6c@lCzrq zsArZUSG!06%5g3Mdf!fL5@KZkX=l5 zPj_`sb#=X}>VCdfE5E+0s$*$qAe!^@mgWzY?Y8??zQ z=pP=|y6p!+%XJ`fYlyG(TirgU-4Ok*{A9U=kG7I=5Dc@DAaaf6Qe3;ddnK|j@4kJb z1IgE1Rc;o8Mi?vO(eQ-71BqCqjM<*rQOC-jqOeHYV`FCPW7eUKlx?zZ(B{FMH1rl_ z3zUv}iG$ZJ^8#oks?zrU7&F>6$y1kfM$(3)vy#q9YDzjUX;ac;-26oeqZf8g;eDZV ze2<-D-#u|%ov0HnTI8k9(pVis#yu&`txv82T-f6Bn*XDD#@78$I*bVg3%jsSYiz^L z2BPnJVd#bJ(x~PRg@Dbs0>A4=qpI8QMWP=-x7-_5yV&zgqj;Or@2D=k&~*Z6*m0x2 z7|p;6HoYikx2lfodVwb-a7L!r+k{2&GoudI2?FF z6d`47+P2^GBipu$S78=tk5zZeI@TX}y=#siUFeImQRKK=gjcH^deQl0{i{g4D9QUT3bqa%o&<6myHG@f36D3_F9a(j1 zNYr!*T9WUV{9g8nqKom)d|m+Zii2V`Ures$|=40Cd~-FWG0OS6{jQ zE)XAHzx2*CZ@m5fbJx##;mxQ&xPEcSzY=R{iq}v zrF?U!0D6#2!dpe1Vu!NU)QFTC8cd z2dj(*Cn8CzLNMhxLWsh4mSqe40ap+JPe*C+QP{1;)H7&n>zhCODgAzPrftY2#Ipd< zVW5aQz7f;X-U=`ExBcE`tVe#=14;wW8?@DAiL~7NwtyVD9rg3IzDjE)L@{*%26T86 zjxy()KpRlNBRAnSRCsD69i^itz87m%IvUq#<+6^@n$`;)11&{f+*2pYSiy#wYwO}+ zOtb$l%)C#|(ck&!y?guj@WWP;d5b5Bv_aaYn58;xa9oFWrT`z$;C&jtaRUv9@G8h? z5M+@#?AlJa+jHYa=38v(YCMsuFxKEmkE*Z=7aZ7tHt@)$0!R=hQAg;55)YZoH2eRl zK>dgU3%LS~`xFSZ5xm56L`b*OY7sN?8O@ve;o*}XVk{Qrfso@AvYH~R@;E-wg z-vLK>-}0BH5p#$?Uq7K(!z1$GT%tBcZKNGGeU`F}vv^?zG}O!}1cG+xv|K1b3@ zcpHwv7EW)|v%q%X(2gIH@_;LslhBRNC7VO0vrCzgbg~Iv6?kDv@vkQN4BV|MC6n$p z16yiEmWF)ds1-?fi*}i3e2=6{G^r|OMF)}&BZ!=C#_W>Yp&t#%UC^KL62S>2)-x$Y z3Pps8G1j;VSNqslt+0v8wMlW4O-z{tsyiQ(vO7B5u@0W!Cu7FOBAb-Pg|Tw8Aa0Cx z)JjeEGMnhV7qT~A8mmn65UR(!Qm6ukX_qjULb3Rx4v^?NGkf z+LqKInuinVIyW&4zrUPmm*T=e_{b-}g!cn~DjuiT915`kH|h1b_%fQ?Wf@m2$~E)- zh!rO;6tUz+NWAH5$g{Tq8Ymnm zrOkaxPyDsBSiUAGwkHrI^kqS!;P<$Y!-0SqdAU4 zJ{dEO9;=;ZV%WDX!km@PG4KE;orUQ57$>4VC0eBNB;bL4sbHj$jEt6|6P=Ujg%o3> zDcwAv!+3R!oB?t%UhB*!vjA+xrSya)*Rh`jH~mydj>eG(+KgVYHe}tKg7PcMX zJ3ZIKNjPwaffM0$erGaj!OzK)79D)I{LL*dj9M8lfi!NoK_6$ngA{c1lst)L^I;rd z-FM}IkW)mh_;J7%F+2l^oB2iFttp`)!~s4s_Lq)Hc*<% zf-(oMR7cMO=mOddv^124O7w7Ikk6Wfo77K_1otV}6UKT!*n;4sq}Q>l92 zM#LkY|De>U1WzgFsZy=?1m?tez;c;pPio*R=X}`#qMSptw)P+-?tcbl`u~O^N8hBY z3f~EUHy^o>>&eiV<*zvk30`SRKixK(!95m5f^5L3o;IY+qXok02JR{N({$OkOU#2| zhK`$oLlM z9;oMZJ=>1Uwv9WfVL z(W16TiAa4sOSR{Tyg)=cE&`!U90Y+yyhnuA7}wIv6x?eC_+EZ&L3(_WnCJ#V-e1w- zIi#%CG<0a9esaz*b+c&FuPAFLO{4K-e%IA?{GM&EUuZ8`CoXUK9A579>6Ns0e#i9& zblGan-q&X>9Wl2RMM(G}>9 z^uEF`y1`3(K5u&S!EhzCAWoBKZdh6xKZ GQ2!sG1Sk3c diff --git a/autofocus.py b/autofocus.py index 0f42585..5572279 100644 --- a/autofocus.py +++ b/autofocus.py @@ -26,10 +26,12 @@ class autofocuser(QtCore.QObject): self.ch.openWaitForAttachment(5000) self.ch.setEngaged(True) self.full_scale = 27300 - self.position = self.ch.getTargetPosition() self.image_count = 0 self.track_position = False self.pool = ThreadPool(processes=3) + self.velocity = 0 + self.ch.setDataInterval(100) + self.position = 0 self.status_dict = {'current limit':self.ch.getCurrentLimit, 'control mode': self.ch.getControlMode, # 'setting min position: ': self.ch.setMinPosition(0), @@ -40,13 +42,25 @@ class autofocuser(QtCore.QObject): 'target position': self.ch.getTargetPosition, 'acceleration': self.ch.getAcceleration, 'engaged?': self.ch.getEngaged, - 'max velocity:': self.ch.getMaxVelocityLimit} + 'max velocity:': self.ch.getMaxVelocityLimit, + 'data interval': self.ch.getDataInterval, + 'min data interval': self.ch.getMinDataInterval} for k,v in self.status_dict.items(): comment('{}: {}'.format(k,v())) + self.ch.setOnVelocityChangeHandler(self.velocity_change_handler) + self.ch.setOnPositionChangeHandler(self.position_change_handler) # self.step_to_position(self.full_scale) # self.autofocus() + def velocity_change_handler(self,self2,velocity): + # print('VELOCITY CHANGED:',velocity) + self.velocity = velocity + + def position_change_handler(self,self2,position): + # print('POSITION CHANGED:',position) + self.position = position + @QtCore.pyqtSlot('PyQt_PyObject') def vid_process_slot(self,image): self.image = image @@ -57,152 +71,80 @@ class autofocuser(QtCore.QObject): self.position = self.ch.getPosition() return self.position - def step_to_position(self,position): + def step_to_relative_position(self,position): + self.ch.setAcceleration(2000) + self.ch.setVelocityLimit(2000) # TODO check if the given position will make us exceed the range - self.ch.setTargetPosition(self.ch.getTargetPosition() + position) - while self.ch.getIsMoving() == True: - time.sleep(.1) + self.ch.setTargetPosition(self.position + position) + # while self.ch.getIsMoving() == True: + # time.sleep(.1) # print(self.ch.getTargetPosition()) def roll_forward(self): - self.track_position = True self.ch.setControlMode(1) - self.ch.setAcceleration(750) + self.ch.setAcceleration(1500) self.ch.setVelocityLimit(-5000) - res = self.pool.apply_async(self.position_tracker, (5000,750,-1)) - return res def roll_backward(self): - self.track_position = True self.ch.setControlMode(1) - self.ch.setAcceleration(750) + self.ch.setAcceleration(1500) self.ch.setVelocityLimit(5000) - res = self.pool.apply_async(self.position_tracker, (5000,750,1)) - return res def stop_roll(self): self.ch.setVelocityLimit(0) - self.track_position = False - self.ch.setControlMode(1) + self.ch.setControlMode(0) self.ch.setAcceleration(10000) comment('focus at {} steps'.format(self.get_position())) def swing_range(self): self.ch.setVelocityLimit(2000) - self.ch.setTargetPosition(self.full_scale-2500) - - def get_velocity(self): - try: - vel = self.ch.getVelocity() - return vel - except: - return None - - def position_tracker(self,max_velocity,a,direction,x): - # always assume that initial velocity is 0 - print('tracking') - v = 0 - t0 = time.time() - if direction == -1: a = -a - i = 1 - positions = [] - self.track_position = True - while self.ch.getIsMoving() == True: - dt = (time.time()-t0) - # check if we are at max velocity - if v >= max_velocity: - x += v*dt - else: - x += v*dt + 1/2*a*dt**2 - v += a*dt - if v > max_velocity: v = max_velocity - t0 += dt - i += 1 - comment('position tracking x: {} v: {} a: {}'.format( - x,v,a)) - positions.append(x) - time.sleep(.1) - return positions - - - def change_magnification(self,index): - print('changing mag') - if index == 4: - self.ch.setTargetPosition(16718) + self.ch.setTargetPosition(-self.full_scale+2500) @QtCore.pyqtSlot() def autofocus(self): - print(self.ch.getMaxVelocityLimit(), - self.ch.getAcceleration(), - 1,0) - # we want to roll the focus forward steadily and capture - # laplacian variances as we do so, until we find a max - - position_result = self.pool.apply_async(self.position_tracker,(2000, - self.ch.getAcceleration(), - 1,0)) - self.pool.apply_async(self.swing_range) - + range = 4000 + variance1, location1, variances1 = self.focus_over_range(range) + self.step_to_relative_position(-range) + variance2, location2, variances2 = self.focus_over_range(-range) + variances2.reverse() + total_variances = variances2 + variances1 + self.position_and_variance_signal.emit(([],total_variances)) + if variance1 > variance2: + self.ch.setTargetPosition(location1) + elif variance2 > variance1: + self.ch.setTargetPosition(location2) + while self.ch.getIsMoving() == True: + time.sleep(.1) + + def focus_over_range(self,range): + self.pool.apply_async(self.step_to_relative_position(range)) variances = [] - + positions = [] + old_position = 0 while self.ch.getIsMoving() == True: - time.sleep(.01) QApplication.processEvents() + new_position = self.position + if old_position != new_position: positions.append(self.position) + old_position = new_position img = self.image[512:1536,411:1233] variance = cv2.Laplacian(img, cv2.CV_64F).var() - comment('variance calculated {}'.format(variance)) variances.append(variance) - positions = position_result.get() - # positions = [p*.94 for p in positions] - # now we want to find the point which corresponded to the highest - # VoL unit_scaled_location_of_highest_variance = variances.index(max(variances))/len(variances) print('location of highest variance: {}'.format(unit_scaled_location_of_highest_variance)) closest_position = int(np.rint(len(positions)*unit_scaled_location_of_highest_variance)) print('closest_position',closest_position) print('max variance of {} occurred at location {}'.format( max(variances),positions[closest_position])) - self.ch.setTargetPosition(positions[closest_position]) - self.position_and_variance_signal.emit((positions,variances)) - # comment('focus at {} steps'.format(self.get_position())) + # self.ch.setTargetPosition(positions[closest_position]) + # self.position_and_variance_signal.emit((positions,variances)) while self.ch.getIsMoving() == True: - time.sleep(.1) - self.relative_focus() - - def relative_focus(self): - # first get our initial variance - img = self.image[512:1536,411:1233] - variance = cv2.Laplacian(img, cv2.CV_64F).var() - QApplication.processEvents() - # now move in each direction - self.step_to_position(250) - img = self.image[512:1536,411:1233] - variance_backward = cv2.Laplacian(img, cv2.CV_64F).var() - QApplication.processEvents() - self.step_to_position(-500) - img = self.image[512:1536,411:1233] - variance_forward = cv2.Laplacian(img, cv2.CV_64F).var() - print('initial vairance: {} backward variance {} forward variance {}'.format( - variance,variance_backward,variance_forward)) - if variance_backward > variance and variance_backward > variance_forward: - print('moving backward') - self.step_to_position(250) - elif variance_forward > variance and variance_forward > variance_backward: - print('moving forward') - self.step_to_position(-250) - elif variance > variance_forward and variance > variance_backward: - print('max found, staying put') - self.step_to_position(250) - self.relative_focus() + time.sleep(.1) + + return max(variances),positions[closest_position],variances if __name__ == '__main__': a = autofocuser() - a.track_position = True a.autofocus() - # time.sleep(4) - # a.stop_roll() - a.track_position = False - # print(b.get()) diff --git a/directory_organizer.py b/directory_organizer.py new file mode 100644 index 0000000..e4b15c1 --- /dev/null +++ b/directory_organizer.py @@ -0,0 +1,47 @@ +import os +import shutil +experiment_folder_location = os.path.join(os.path.dirname(os.path.abspath(__file__)),'Experiments') + +# first lets delete all experiments with no pictures in them +for name in os.listdir(experiment_folder_location): + files = ''.join(os.listdir(os.path.join(experiment_folder_location,name))) + if '.tif' not in files: + response = input('WARNING directory {} found not to have files. Type Y to Delete\n'.format(name)) + if response == 'Y': + shutil.rmtree(os.path.join(experiment_folder_location,name)) + print('deleting:',name) + +def get_480mb_worth_of_files(directory): + paths_out = [] + running_total = 0 + # files = filter(os.path.isfile, os.listdir(directory)) + # print(files) + files = [os.path.join(directory, f) for f in os.listdir(directory)] # add path to each file + files.sort(key=lambda x: os.path.getmtime(x),reverse = True) + for file in files: + size = os.path.getsize(os.path.join(directory,file)) + running_total += size/10**6 + paths_out.append(file) + if running_total > 480: + return paths_out + return paths_out + +# next lets sort the pictures into groups of < 500mb so they can be uploaded to owncloud +directories = os.listdir(experiment_folder_location) +directoryies_out = [os.path.join(experiment_folder_location,'sd_' + name) for name in directories] +for name in directoryies_out: + os.makedirs(name) + +print(os.getcwd()) +for i,directory in enumerate(directories): + subdirectory = os.path.join(experiment_folder_location,directory) + print('fixing directory:',subdirectory) + subdirectory_int = 0 + while len(os.listdir(subdirectory)) > 0: + new_dir = os.path.join(directoryies_out[i],str(subdirectory_int)) + os.makedirs(new_dir) + from_paths = get_480mb_worth_of_files(subdirectory) + for path in from_paths: + file_name = path.split('\\')[-1] + shutil.move(path,os.path.join(new_dir,file_name)) + subdirectory_int += 1 \ No newline at end of file -- GitLab