Open ukoethe opened 13 years ago
Maybe I don't know GitHub well enough, but I don't see the patch here?
Anyhow, the longer I think about this, and the more work goes into it, the more sure I am that we really want to use QGraphicsView…
BTW, Rainer, I have lost overview on all the forked image viewers / overlay implementations, but let me tell you again what code I have already written:
But see above, I would really think that we can do even better with QGraphicsView. And starting with everything in Python, just using PyQt, NumPy, and qimage2ndarray should make it possible to implement a better viewer rather quickly, probably even without sacrificing any performance.
Oh, BTW, Rainer, concerning performance: A big penalty comes with antialiasing, or with arbitrary coordinate transformations done in Qt. I think if you have large data (many points / large polygons) it might still make sense to precompute zoomed coordinates for the display (and just leave the translation to Qt). Then, Qt4 should not be slower than Qt3 was.
Here is what I really want: a lightweight PyQt-based image viewer that can be shipped with VIGRA. It should be very easy to install, preferably without installing Qt (i.e. PyQt should suffice, but that's probably impossible, given the need for qimage2ndarray). Required features:
If I need a more powerful viewer, I'll very likely go with the one that is being developed in the ilastik project (and which already uses QGraphicsView). But for the simple viewer, I will accept any solution that's sufficiently clean -- please make a pull request if you have something (e.g. where exactly is the Qt4 port of interactive2, and can it be adapted quickly to vigranumpy?)
Hello Hans,
the patches are placed here: http://github.com/hzg1/vigra inside the overlay-viewer branch.
Concerning performance, you are right, disabling antialiasing helps a lot (at least on my current hardware).
ATM, I'm quite confident with the current implementation, however, I appreciate any improvements (namely in terms of QGraphicsView) without losing options available at this time.
I implemented the improved parent handling and the OverlayGroup
class (see branch 'overlay-viewer' in this repo), and it works in principle. A problem I noticed are the size and position handling of TextOverlay
(which now contains just a single text): When a TextOverlay
is added on its own, the text size is independent of the viewer's zoom. If the TextOverlay
is part of a OverlayGroup
, the text size changes according to the zoom level (which I personnally like better).
I also tried the SVG writer that comes with PyQt, and it works nicely:
import PyQt4.QtSvg
g = PyQt4.QtSvg.QSvgGenerator()
g.setFileName('test.svg')
g.setSize(q.QSize(256,256))
g.setViewBox(q.QRect(0,0,256,256))
g.setTitle("SVG Generator Example Drawing")
p = QtGui.QPainter()
p.begin(g)
w.viewer().paintImage(p, q.QRect(0,0,256,256))
w.viewer().paintOverlays(p, q.QRect(0,0,256,256))
p.end()
Here's the code to display overlays in the new design:
w = i.show()
t1 = vigra.pyqt.overlays.TextOverlay('blah', [100,10])
t2 = vigra.pyqt.overlays.TextOverlay('foo', [100,100])
l = vigra.pyqt.overlays.OverlayGroup([t1, t2], parent=w.viewer())
t3 = vigra.pyqt.overlays.TextOverlay('hallo', [50,50])
w.viewer().addOverlay(t3) # if parent was not given in the constructor
I played a bit around with the QSvgGenerator. When I use the values from the ImageViewer
from PyQt4 import QtSvg, QtCore, QtGui
g = QtSvg.QSvgGenerator()
g.setFileName('test.svg')
size = w.viewer().sizeHint()
viewRect = QtCore.QRect(w.viewer().upperLeft(), size)
g.setSize(size)
g.setViewBox(viewRect)
g.setTitle("SVG Generator Example Drawing")
p = QtGui.QPainter()
p.begin(g)
w.viewer().paintImage(p, viewRect)
w.viewer().paintOverlays(p, viewRect)
p.end()
I end up with an output not much different from my own generator, which is fine for me. Interestingly, the image is coded directly into the svg file. Still I like to have a simple option to get the original Image, not zoomed or normalized, into the svg file.
Concerning your changes for TextOverlay, I'm a bit worried about performance. Maybe this is not sensible. ATM, I use TextOverlay for displaying labels of regions, i.e. numbers of 1-4 digits. These are in one example more than 40, but I can easily imagine of hundreds of labels. That would make hundreds of TextOverlays, combined in one OverlayGroup. I'm not sure if it makes a big difference calling the draw method of hundreds of overlays which is quite simple now, or if it's better to have a single draw method, looping over all entrys in the list, which is the previous solution. Compared to the Point- and EdgeOverlay, also those expect some kind of a list of elements, though the matter of positioning is simpler there, as the position is implicit.
Concerning your changes for TextOverlay, I'm a bit worried about performance. Maybe this is not sensible.
I dont think there is a much of a difference: The loop just moved from TestOverlay
to OverlayGroup
, so there is only one additional function call. Of course, one could refactor the code a little to ensure that common setup calls are executed only once (before the loop).
BTW, when the painter is configured in a draw() function, the original settings are not restored at the end of draw(). I think this should be changed.
Meanwhile I merged all your changes and can't notice a big difference in performance regarding the method of text handling.
I found a possibility for choosing whether the text should be zoomed with the image or not. Personally, I prefer the second case. I use text for information purposes only, not as objects of the image itself. So the text should have a reasonably readable size, no matter how the image is zoomed. Maybe two or more text overlays are overlapping itselves at 1:1 zoom. Only by using a fixed size, those labels will get readable when zooming in.
Though I never used 'Grid' as coordinateSystem, I had to translate objects by (0.5, 0.5) on two occasions. I didn't understand why, but now in all my test cases, everything is positioned where it should.
I fixed a small bug and uploaded the change to my repo (branch overlay-viewer
). Can you please provide a little demo programm that reads an image (e.g. vigra/src/examples/lenna_color.gif
) and adds some representative overlays?
This is a patch that Rainer Herzog is currently implementing. A few remarks:
OverlayGroup
that acts as a container of overlays and sets theparent
of its suboverlays automatically. Suboverlays would also inherit the group's color and font settings as a default.Once the ilastik image viewer is finished, this functionality should be carried over there.