How to erase cv::circle from display window - c++

I use OpenCV library for drawing circles on image.
I need to erase last circle which was drawn on window by clicking on right button click.
Currently, I wrote workaround, I replace red circle by white.
but seems there is another solution such as erase it.
How I can update my UI?
std::vector<Point2f> right_image; // stores 4 points that the user clicks(mouse left click) in the main image.
if (e == EVENT_RBUTTONDOWN && right_image.size() > 0) {
float x0 = right_image[right_image.size()-1].x;
float y0 = right_image[right_image.size()-1].y;
cv::circle(dispImg, cv::Point(x0, y0), 10, cv::Scalar(255, 255, 255), 3);
cv::imshow(cv::String(fullWindowName), dispImg);
right_image.pop_back();
}

It will be faster to store image without any overlays, and redraw circles each frame. If you want to append, move or delete circle just remove it from the list of objects to plot.

If you are developing a raster drawing program you could implement a simple undo. You would have to use an off-screen image (dispImg) and a smaller 'undo' image. Before drawing the circle on the off-screen image, save the part of the image that will be occupied by the new circle into a new, smaller image. You must also save the position of the image. Then when you want to erase the circle, copy the saved image back to the off-screen image to the position that was saved along with the undo image. Finally, draw the off-screen image to the window (imshow).
You could extend this to multiple levels of undo, assuming you have enough memory.
If your program is a vector drawing program, a display list like the one suggested by Andrey is a better option.

Related

DrawingArea: fill area outside a region

I have followed this gtkmm tutorial on how to draw shapes and fill them with colors (e.g. A red disc on a transparent background). I was also able, from this example, to derive another example with a red disc on a blue background.
However, what I would really need is a transparent disc with a blue background that fills everything minus the disc area, which should stay transparent.
So with cairo, the usual workflow is:
Create a surface
Draw a shape (e.g. draw a circle)
Fill the circle, so that it becomes a disc.
I would need some workflow that achieves something like this instead:
Create a surface
Draw a shape (e.g. draw a circle)
Fill the area outside the circle, so that I have a colored background with a transparent "hole" in the middle.
I have done some research on this on the web but all examples seem to assume that we want to fill the inner region of a shape (which I must admit is more typical).
How could I do this?
P.S. I have added the C tag because I don't mind if you prefer to use C (or even Python).
Draw your circle and draw a rectangle containing all the visible area. Set the cairo fill rule to even/odd. Fill. Done.
cairo_save(cr); // Save the state
cairo_arc(cr, 42, 42, 21, 0, 2*M_PI); // Draw circle
cairo_rectangle(cr, 0, 0, width, height); // Rectangle containing everything
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
cairo_fill(cr);
cairo_restore(cr); // Restore default fill rule (optional; pairs with save above)
IMHO, The function of 'Draw outside the circle' is complex to the graphic framework. It may also be ambiguous if you draw more than one circle filled outside.
As graphic shapes drawn later are placed 'on' the ones drawn former. What is needed is that draw a rectangle to fill the entire graphic context before drawing other shapes. This is defined as clear with the background color in some frameworks.
the workflow would seem like:
1. Create the surface.
2. Draw the background colored with what outside the circle.
3. Draw the circle filled with a specific color, e.g. white.
As a result, the circle would cover the background.
If insist on draw the circle first, please search Flood Fill Algorithm, which is used to draw on images. However, it is needless and costly to achieve the screen pixels and play such algorithms when drawing on screen.
I find
Example Application: Creating a Clock with Cairo in the later section of the book you provide.
That seems help.

Colour map in Qt

I am new to Qt. I am trying to make a simple map like in the picture bellow, and color each slot a different color based on some value calculated by my program. Then when I tick a checkbox, the value will be displayed on the slot on top of the color. So how can I do this? Any pointing is greatly appreciated.
The trick to drawing such figures is to realize that it's possible to draw a single pixel multiple times.
Each slot is a rectangle, drawn in either white or a color.
On top of those rectangles, you draw the following things:
A grid of black lines
A black circle (not filled)
A number of white circles, around the black circle.
The last step erases colored pixels outside the circle from step 2.

Drawing multiple objects

I have been learning DirectX for a while now & I got to the point of drawing multiple objects to the screen from .obj files. My problem is that if I draw 2 objects, the 2nd draw will be on top of the 1st.
Example:
Obj1 = Cardboard box
Obj2 = Cube
loadStuff_&_draw(Obj1);
loadStuff_&_draw(Obj2);
That would draw the cube outside/front the box even if it is in/behind.
How would I make multiple objects draw together so that they overlap correctly?
The only drawing things I know of are:
Load vertex, index, constant buffers
updateSubresource()
drawIndexed()
Edit:
Here is a picture of a cube in a box. It shows that the cube is behind the box rather than inside. It also shows that the rim of the box clips behind the box. Not sure what happened.
I drew the cube, then drew the hollow box.
This is what the depth buffer (sometimes called the z-buffer) is for. When you write a pixel during the drawing of one object, it records the distance from the viewpoint for that pixel in the depth buffer. Then when you draw a second object that would also write to that pixel, it can compare the new object's depth value at that pixel with the buffered value (from previous objects) and only overwrites the pixel if the new value would be nearer than the old one. If the pixel gets drawn, then the depth value is updated to reflect the closer value.
Some links that might give you some ideas on how to implement this:
http://msdn.microsoft.com/en-gb/library/windows/desktop/bb205074%28v=vs.85%29.aspx
http://www.rastertek.com/dx11tut35.html
https://stackoverflow.com/a/8641210/28875
This depends on how do you set the world matrix of the object, If you want to second object behind the first object, then set the correct world matrix before drawing. suppose object 1 place at origin(0, 0, 0), then you can translate object2 to (0, 0, -10) to make it behind object1. and translate to (0, 0, 10) will make it in front of object1.

"Lantern effect" or show only a part of a scene

I'm trying to show only a part of a background image (game scenenario in the future). The basic way to work is for example, first I draw a background image, after that i need to "hide"/cover the image with some dark or darness (no light, don't know what option must be chosen) and use the mouse click to using a circle or a triangle (my options) show only the part of the image background over with the circle/triangle centered on mouse position. I called this "lantern effect".
First Option: Play with the alpha channel, creating a an square covering all the window size and after that trying to substract the circle area over the alpha square over the image.
Second Option: Play again with a black square covering all the image background and trying to substract a circle/triangle. Try with glLogicOp but this method only plays mixing colors. Don't know how to do operation with 2D polygons with OpenGL.
...
Any other idea or easy example to learn how to do something similar.
Image example:
That's quite easy to achieve actually:
Create black texture with your lantern light shape in Alpha channel. (Texture could be animated)
Render background.
Render Lantern texture centered at your in-game mouse cursor.
Render black padding around the lantern texture to hide everything around till screen edges.
There's no need to use any special blending modes, just an overlay.

Plotting a graph over a QPixmap using QPainter

I need to plot a real time graph keeping the background an image. Let's say I am plotting the graph with a red color.
But the logic I use for plotting is drawing small lines using painter.drawline, where painter is a pixmap painter. Then I am constantly drawing this pixmap using a painter to parent widget on a timer timeout() event. So it appears the updated Image (which is the graph) gets plotted in the Gui.
The pixmap is black in background and plotting pen color is red, So when it reaches the end of screen width, I have to start drawing the graph from position 0, but from the second cycle onwards I have to fill the previously drawn pixels (not the entire pixmap, just a rect of width few pixels and height, height of pixmap) with black color.
But now I need to keep a background image, and draw a graph over it. So the fillling with black color doesn't do, as I have to keep a background an image. So how can I plot a graph over an image like aforementioned?
Is there any way to blend two images such that the pixels only having a particular color (red) in source image is blended/replaced with corresponding pixels in destination image?
Keep previously drawed Ys in memory than fill exactly the same pixels by corresponding background. It's faster and much more reliable.