Closed twVolc closed 1 day ago
Related to this, the SO2 image in the analysis pane doesn't update after updating image registration. This is quite a significant bug as it means you can't see changes related to image registration - could lead the user to think a registration is better or worse than it really is. Dragging the ROI on the SO2 image then updates the figure to the new correct registration, but this shouldn't be required to update the plot. I'm not sure it has always been like this so I'm guessing some of our other updates have led to this bug.
Related to this, the SO2 image in the analysis pane doesn't update after updating image registration. This is quite a significant bug as it means you can't see changes related to image registration - could lead the user to think a registration is better or worse than it really is. Dragging the ROI on the SO2 image then updates the figure to the new correct registration, but this shouldn't be required to update the plot. I'm not sure it has always been like this so I'm guessing some of our other updates have led to this bug.
How would I go about recreating this? Something like:
How would I go about recreating this? Something like:
- Load a new image directory manually (i.e. not through a config file)
- Update the registration
- Switch to the analysis window
Yep I'm pretty sure this is how I did it. I think you'll notice if you then change the ROI the analysis window will update and things will look quite different. I can't remember for certain though.
If I click OpenCV straight away again, the following error is thrown:
Okay I've got the reason for this error.
When you first load up the GUI it will load an image registration, so self.got_cv_transform
will be set to True
. Because of this, if you press the "OpenCV ECC" radio button again it will run this bit of code but skip the self.cv_generate_warp_matrix()
method.
It will still run the self.cv_warp_img()
method, and this will throw the error at the below section of code, because the attribute self.warp_matrix_cv
is set to False
when you click the radio button:
I can see two potential options here:
self.warp_matrix_cv
is False
- _This will retain the current functionality but will recalculate the warpmatrix every timeWhat do you think? Any alternate suggestions?
Great good spot!
It would be nice to avoid regenerating the warp matrix every time OpenCV is clicked, as it makes the GUI a little unresponsive - i.e. it could be useful to toggle between OpenCV and No registration or control point quickly, to see differences. But that being said, I think there are cases (albeit unlikely) where you might want to rerun the OpenCV registration - i.e. if you load in a new image sequence from a different volcano, or even if you just want to play around with the OpenCV tuning parameters. Perhaps the best solution is acutally to have another button that is "Run OpenCV" which runs the registration again and updates everything to the new setup? The radio button for OpenCV could be disabled until self.got_cv_transform
is True
, which would happen either by running OpenCV registration or by loading in a registration file (either on start-up or with the GUI option).
How does this sound? Would this be relatively straightforward to implement?
Initial changes in draft PR #245
Just to make sure I understand what you're saying, you would like:
Is that right?
Assuming it is, I have additional questions:
2b000ce6
) altered the code to fix a bug (that I don't fully understand) so that it runs process_pair()
rather than load_sequence()
to reload the optical depth plots, but this means you then have to reload the image sequence to update the optical flow. Would you like me to take a look at that?
- Clicking the radio buttons to toggle between existing registrations without regenerating the warp matrix
- The addition of a run button that will generate the warp matrix and transform the image
The run button could just be placed within the OpenCV widget. The control point registration is run whenever the points are saved and there are a matching number of points on each plot, so as far as I understand the radio button for this only toggles between registrations anyway. OpenCV is the one that has slightly od functionality at the moment. The radio button for both would ideally be disabled until there is an existing registration for them.
- For 1. do you want me to update all the optical depth plots too (i.e. the one in the analysis view)? This will flipping between the options slower, and we can have it update these plots when the run button is pressed.
Yes we need to update these plots when we change registration. I think this happens at the moment anyway, or at least it's supposed to.
- I saw that a commit from quite a while ago (
2b000ce6
) altered the code to fix a bug (that I don't fully understand) so that it runsprocess_pair()
rather thanload_sequence()
to reload the optical depth plots, but this means you then have to reload the image sequence to update the optical flow. Would you like me to take a look at that?
It sounds like this isn't ideal. I must have messed something up here. Really when registration shifts we would want to update everything as it could change all of the processed results. There might be a clever way of doing this that means we don't have to reload everything each time we toggle between registrations - i.e. if each array is saved as an attribute so rather than regenerating them you just switch to the other array. When re-running this would of course mean we need to regenerate things, but when just toggling between without re-running we could just grab the respective optical depth and optical flow arrays and plot them?
Okay, I think I've got it, but just to make sure:
Whenever any radio button is picked the corresponding optical depth plots should all be updated too.
The radio button for both would ideally be disabled until there is an existing registration for them.
Not sure I fully understand this, do you mean for the Control Points and OpenCV options?
It sounds like this isn't ideal. I must have messed something up here. Really when registration shifts we would want to update everything as it could change all of the processed results. There might be a clever way of doing this that means we don't have to reload everything each time we toggle between registrations - i.e. if each array is saved as an attribute so rather than regenerating them you just switch to the other array. When re-running this would of course mean we need to regenerate things, but when just toggling between without re-running we could just grab the respective optical depth and optical flow arrays and plot them?
I think part of this issue with this is that the way it is now it only loads and processes a single pair of images, and so can't update the optical flow. Whereas before it was using the load_sequence()
method as so is loading the current and subsequent pair, and so can successfully produce the optical flow. I had a go at reverting the code to use the load_sequence()
method and it seemed to work okay. But I don't think the bug you describe in that commit would come up with the way I'm using things, so I'm wary of just changing it to this.
I think saving the outputs for each registration (both for the images, optical depths, and optical flows) would allow faster switching in theory, but I'd have to do a bit of work looking at how to put this together in practice.
Yep that all sounds correct.
Not sure I fully understand this, do you mean for the Control Points and OpenCV options?
Yes - in other words if there isn't a registration available for either then it shouldn't be possible to select that radio button (this isn't how it works at the moment but I think it makes things clearer). So if an OpenCV registration hasn't yet been generated (and one wasn't loaded in the start-up config file) the radio button shouldn't be clickable because there is no OpenCV registration. You should first have to click the Run, which generates the OpenCV registration and then makes the radio button active. I think it would make sense for that run button to switch over to OpenCV registration automatically after generating the registration too - i.e. if I currently have No registration selected, I then click Run for OpenCV it would generate the registration and then apply it and shift the radio button to having OpenCV selected automatically.
I think saving the outputs for each registration (both for the images, optical depths, and optical flows) would allow faster switching in theory, but I'd have to do a bit of work looking at how to put this together in practice.
If this becomes a headache it probably isn't worth it - we could probably lose too much tim to this for relatively little gain. I think really the most important thing here is just making sure there's no bug associated with image registration so that we're confident the data are being processed and displayed correctly (i.e. the priority is just fixing this issue, the rest is just added value that maybe isn't worth the time).
Yes - in other words if there isn't a registration available for either then it shouldn't be possible to select that radio button (this isn't how it works at the moment but I think it makes things clearer). So if an OpenCV registration hasn't yet been generated (and one wasn't loaded in the start-up config file) the radio button shouldn't be clickable because there is no OpenCV registration. You should first have to click the Run, which generates the OpenCV registration and then makes the radio button active. I think it would make sense for that run button to switch over to OpenCV registration automatically after generating the registration too - i.e. if I currently have No registration selected, I then click Run for OpenCV it would generate the registration and then apply it and shift the radio button to having OpenCV selected automatically.
Okay, in that case should the available registrations be reset when a new image sequence is loaded? i.e. the user loads an image sequence, any existing registrations are removed/marked as invalid, and the GUI switches to No Registration?
How should this work for the Control Points option? Looking at the code you can set and save the control points regardless of the mode selected, but it will only run the transformation if the control points option is selected?
If this becomes a headache it probably isn't worth it - we could probably lose too much tim to this for relatively little gain. I think really the most important thing here is just making sure there's no bug associated with image registration so that we're confident the data are being processed and displayed correctly (i.e. the priority is just fixing this issue, the rest is just added value that maybe isn't worth the time).
I agree, so it may be worth having a separate issue for enhancing the image registration options, that can be addressed later.
This isn't quite the same issue but still relates to image registration being buggy. When I load a new image directory (straight after start-up with the default config file) then click to "No registration" the following error is thrown:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\figures_cam.py", line 458, in <lambda>
command=lambda: self.img_reg_select(self.reg_meth))
File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\figures_cam.py", line 550, in img_reg_select
self.pyplis_worker.process_pair(img_path_A=None, img_path_B=None, plot=True, plot_bg=None, overwrite=True)
File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\so2_camera_processor.py", line 3606, in process_pair
img = img_A - self.test_img
UnboundLocalError: local variable 'img_A' referenced before assignment
The image does revert to no registration, so this isn't a breaking error, but it's not clear to me how, if at all, this affects future interactions. I think investigating and fixing this would be beneficial.
If I then click to control point registration (when we don't have one yet) I think this reverts back to No registration as the same error is thrown again.
Following this, I went into the save menu to save a registration file. I then tried loading a new config file and got this error.
Traceback (most recent call last):
File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\menu.py", line 772, in load_config_file
self.reload_config()
File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\menu.py", line 780, in reload_config
self.main_gui.menu.save_frame.load_defaults()
File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\misc.py", line 305, in load_defaults
self.gather_vars()
File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\menu.py", line 905, in gather_vars
tk.messagebox.showinfo('Save settings updated',
File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\messagebox.py", line 84, in showinfo
return _show(title, message, INFO, OK, **options)
File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\messagebox.py", line 72, in _show
res = Message(**options).show()
File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\commondialog.py", line 40, in show
w = Frame(self.master)
File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\__init__.py", line 3124, in __init__
Widget.__init__(self, master, 'frame', cnf, {}, extra)
File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\__init__.py", line 2572, in __init__
self.tk.call(
_tkinter.TclError: bad window path name ".!toplevel"
I'm not sure if this is a result of the registration bug, or a result of me going into the save options window, or entirely unrelated to either of these and just a freak bug.
Loading a control point registration also doesn't seem to do anything (unless the file I'm specifically using doesn't work - I can't attach it here). The registration stays as the current registration.
This isn't quite the same issue but still relates to image registration being buggy. When I load a new image directory (straight after start-up with the default config file) then click to "No registration" the following error is thrown:
Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\gg1tcw\.conda\envs\pycam\lib\tkinter\__init__.py", line 1892, in __call__ return self.func(*args) File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\figures_cam.py", line 458, in <lambda> command=lambda: self.img_reg_select(self.reg_meth)) File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\gui\figures_cam.py", line 550, in img_reg_select self.pyplis_worker.process_pair(img_path_A=None, img_path_B=None, plot=True, plot_bg=None, overwrite=True) File "C:\Users\gg1tcw\Documents\PythonProjects\PyCamPermanent\pycam\so2_camera_processor.py", line 3606, in process_pair img = img_A - self.test_img UnboundLocalError: local variable 'img_A' referenced before assignment
The image does revert to no registration, so this isn't a breaking error, but it's not clear to me how, if at all, this affects future interactions. I think investigating and fixing this would be beneficial.
If I then click to control point registration (when we don't have one yet) I think this reverts back to No registration as the same error is thrown again.
Is this in the current dev branch? Or the draft PR branch #245 ? If it's the dev branch then I'm aware of it, this was the issue introduced by the changes in #195 I mentioned in our chat the other day. The changes I've made in the draft PR branch should fix this. If it's in the draft PR branch then I'll have a but more of a poke around.
Ah ok, this was in dev sorry, so all good on that front!
I'll still have a look at the other two things you mention next time I'm working on this issue, just to make sure I haven't missed anything
Notes from our conversation about this earlier:
Additional info:
I think that's everything. Let me know if not.
I've encountered bugs with image registration a number of times when moving between data and generally doing processing. Sometimes it's been hard to keep track of what exactly I've done to recreate the error, so I've just let it slide, but think I need to document this now as I've found at least one way to easily reproduce a bug:
Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\thom_\anaconda3\envs\pycam\lib\tkinter\__init__.py", line 1892, in __call__ return self.func(*args) File "C:\Users\thom_\Documents\Work\pycam_dev\PyCamPermanent\pycam\gui\figures_cam.py", line 466, in <lambda> command=lambda: self.img_reg_select(self.reg_meth)) File "C:\Users\thom_\Documents\Work\pycam_dev\PyCamPermanent\pycam\gui\figures_cam.py", line 540, in img_reg_select self.pyplis_worker.register_image(**kwargs) File "C:\Users\thom_\Documents\Work\pycam_dev\PyCamPermanent\pycam\so2_camera_processor.py", line 1147, in register_image self.img_B.img_warped = self.img_reg.register_image(self.img_A.img, self.img_B.img, **kwargs) File "C:\Users\thom_\Documents\Work\pycam_dev\PyCamPermanent\pycam\so2_camera_processor.py", line 4066, in register_image warped_B = self.cv_warp_img(img_B) File "C:\Users\thom_\Documents\Work\pycam_dev\PyCamPermanent\pycam\so2_camera_processor.py", line 4022, in cv_warp_img img_warped = cv2.warpAffine(img, self.warp_matrix_cv, (sz[1], sz[0]), cv2.error: OpenCV(4.9.0) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\imgwarp.cpp:2757: error: (-215:Assertion failed) (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 2 && M0.cols == 3 in function 'cv::warpAffine'
I would suggest keeping this issue to document any other bugs we may find relating to this.
For context on how the warping is implemented: rather than creating a new
PyplisWorker
attribute calledimg_B_warped
I decided to just givePyplisWorker.img_B
a new attribute calledimg_warped
. Perhaps things aren't correctly updated at times or there is an artifact of old warping that hasn't bee updated, for instance in other attributes later in the processing pipeline that stem fromimg_B_warped
(e.gPyplisWorker.vign_corr_B_warped
)