Very simple question. I am trying to use a vtkImageTracerWidget to represent user input in my segmentation algorithm. My inspiration for this widget choice was David Doria's code here.
In other words, the user draws on the image, and it acts basically as a brush, to seed the algorithm.
I am currently using the following code:
tracer->GetLineProperty()->SetLineWidth(20.0);
It works perfectly if I try to make the line width 1.0. Or if I try to change the line color using SetColor() in the same manner. However, I just cannot get it to make the line any wider than what seems to be 5.0. I would like the user to use a big brush to make large, crude input. The 5.0 vtkImageTracerWidget's line does not suffice.
How can I increase the size of the user input? Is there perhaps another widget I should be using? I checked the max line width, and it was on the order of 10^36, so that is clearly not the issue.
Thanks so much!
Goodwin Lawlor's answer here http://vtk.1045678.n5.nabble.com/Problem-with-vtkPolyLine-width-greater-than-20-td5667414.html#a5672819 explains that this is an OpenGL limitation. You can verify that the max GL line width corresponds to the line width by checking it (after there is a GL context, which means sometime after you've called renderWindowInteractor->Start() ). For testing, you could do it in an interactor style event or similar) with:
// Initialize so we get these values back instead of garbage if the call doesn't work
GLfloat lineWidthRange[2];
lineWidthRange[0] = 123;
lineWidthRange[1] = 123;
glGetFloatv(GL_LINE_WIDTH_RANGE, lineWidthRange);
std::cout << "GL_LINE_WIDTH_RANGE: " << lineWidthRange[0] << " " << lineWidthRange[1] << std::endl;
On my hardware, this printed
GL_LINE_WIDTH_RANGE: 0.5 10
which indicated that 10 (as I saw experimentally) is the largest line that OpenGL will draw.
Related
I'm new to Open Inventor 3D Graphics API and I just want to draw a line between given to 3-D coordinates. Let's say the first point is 0,0,0 and the second is 1,1,1. The documentation and examples of this API are really awful and can't get it out right. I'm using Visual Studio.
If you just need to set the base color (what Open Inventor & OpenGL call diffuse color), which is usually the case for line geometry, then you can set it directly in the SoVertexProperty node.
For example, to make the line in the previous example 'red', add this line:
vprop->orderedRGBA = 0xff0000ff; // By default applies to all vertices
or, more conveniently:
vprop->orderedRGBA = SbColor(1,0,0).getPackedValue();
If you need more control over the appearance of the geometry, add an SoMaterial node to the scene graph before the geometry node.
Assuming you're just asking about creating the line shape - just store the coordinates in an SoVertexProperty node, set that node in an SoLineSet node, then add the line set to your scene graph. Open Inventor will assume that you want to use all the coordinates given, so that's all you need to do.
For just two coordinates it may be easiest to use the set1Value method, but you can also set the coordinates from an array. You didn't say which language you're using, so I'll show the code in C++ (C# and Java would be essentially the same except for language syntax differences):
SoVertexProperty* vprop = new SoVertexProperty();
vprop->vertex.set1Value( 0, 0,0,0 ); // Set first vertex to be 0,0,0
vprop->vertex.set1Value( 1, 1,1,1 ); // Set second vertex to be 1,1,1
SoLineSet* line = new SoLineSet();
line->vertexProperty = vprop;
sceneGraph->addChild( line );
Line thickness is specified by creating an SoDrawStyle property node and adding it to the scene graph before/above the geometry node. Like this:
SoDrawStyle* style = new SoDrawStyle();
style->lineWidth = 3; // "pixels" but see OpenGL docs
parent->addChild( style );
I want to have a single Qt application showing two windows on different display outputs(screens) on my Ubuntu 14.04 computer. Does someone know how to do that?
The documentation of Qt for embedded linux is what I could find so far but it did not help me really.
Edit:
Based on your comments, I've done this but it doesn't work as it should:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view1(QUrl(QStringLiteral("qrc:/Screen1.qml")));
qDebug() << app.screens().length();
QScreen* screen1 = app.screens().at(0);
QScreen* screen2 = app.screens().at(1);
view1.setGeometry(0,0,200,200);
view1.setScreen(screen1);
view1.show();
QQuickView view2(QUrl(QStringLiteral("qrc:/Screen2.qml")));
view2.setGeometry(0,0,200,200);
view2.setScreen(screen2);
view2.show();
return app.exec();
}
The debug output is: 2
This code is putting both views to the same display output, although the qDebug output gives the correct number of display outputs with correct names.
Your mistake is wrong geometry. In these 2 lines of code, you place both windows on same position:
view1.setGeometry(0,0,200,200);
view2.setGeometry(0,0,200,200);
Instead of this, you can set the position (not sure if you need size also):
view1.setGeometry(screen1->geometry().x(),screen1->geometry().y(),200,200);
view2.setGeometry(screen2->geometry().x(),screen2->geometry().y(),200,200);
To change the position instead of changing both the position and the size, you can use the function move.
P.S. There may be some small typos as I wrote this code by memory, but the main idea should be clear for you.
I suggest you to take a look at this question and this answer on another question. Also, refer to the documentation of QDesktopWidget. Hope that helps !
I want to mask the moving objects from video.
I found that OpenCV has some built-in BackgroundSubtractors which could possibly saving my time a lot. However, according to the official reference, the function:
void BackgroundSubtractorMOG2::operator()(InputArray image, OutputArray fgmask, double learningRate=-1)
should output a mask, fgmask, but it doesn't. The fgmask variable will contain the "contour of the mask" instead after invoking above method. That's weird. All I want is a simple closed region filled with white color(for example) to represent the moving objects. How could I do that?
Any reply or recommendation would be very appreciate. Thanks a lot.
Here's my code:
int main(int argc, char *argv[])
{
cv::BackgroundSubtractorMOG2 bg = BackgroundSubtractorMOG2(30,16.0,false);
cv::VideoCapture cap(0);
cv::Mat frame, mask, _frame, _fmask;
cvNamedWindow("mask", CV_WINDOW_AUTOSIZE);
for(;;)
{
cap >> frame;
bg(frame,fmask,-1);
_frame = IplImage(frame);
_fmask = IplImage(fmask);
cvShowImage("mask", &_fmask);
if(cv::waitKey(30) >= 0) break;
}
return 0;
}
A snapshot of the output video is:
p.s. My working environment is OpenCV2.4.3 on OSX 10.8 and XCode 4.5.2 with apple LLVM compiler 4.1.
If you want to acquire the whole objects filled with white pixels in the foreground then I would ask you to tell me something about your experience.
My question is, for the code, you mentioned above, do you get more white pixels when you generate more motion in front of your camera?
If yes then there are two paramenters to learn about for your requirement.
First is the History parameter. which you have configured as 30 in the constructor BackgroundSubtractorMOG2(30,16.0,false);. You can test this param by incresing, say to 300. It will maintain the motion history of the object in the foreground. So if you have moved completely from your starting location within the 300 frames then you will get whole object covered with white pixels as you want. but it will be erased gradually. So it cannot give you the 100% solution.
The second parameter is called learning rate. In the code you mentioned bg(frame,fmask,-1); where -1 is your learning rate. you can set it to 0.0 to 1.0 and default is -1. When you set it 0, you will get what you want for the objects which are not part of the frame in the starting of the video. You can call this kind of object "foreign objects". You will get foreign object covered with white pixels.
Explore your testing from the information I have mentioned above and share your experience.
As the title says, the height of my tabs is not increasing as it should, my code looks like this:
JTabbedPane jtp = new JTabbedPane();
JLabel iconInTab = new JLabel(new ImageIcon("myImage.png"));
iconInTab.setPreferredSize(new Dimension(100,80)); // is the size of my Image, I've also try to do this using getSize
jtp.addTab(null,new JPanel());
jtp.setTabComponentAt(0,iconInTab);
I've also try this using html but it did not work either:
jtp.addTab("<html><p><p><p></html>",new ImageIcon("myImage.png"),new JPanel());
with the first code the problem is not the change of the size horizontally (the width change correctly), the problem is only on the height, with the second code, if I add multiple lines inside the html code, the text appear incomplete (just show the middle line) (also the width behaves as expected, the problem is the height). . .
why is this happening? or how could I get this done?
Note: S.O.: Mac OS X 10.8.1
Solved!!! The problem was that the default UI over MAC OS X (com.apple.laf.AquaTabbedPaneContrastUI), you only need to change it to the basicTabbedPaneUI (or the one of your preference), in my particular case I need to extend this class (it was a pain in the *, because what I wanted was really complex) to get the look & feel that I was expecting, if you have the same trouble just do this before adding your tabs:
myTabbedPane.setUI(new BasicTabbedPaneUI());
Note: Checking the default UI of your TabbedPane, may solve many different problems.
This question kind of starts where this question ends up. MATLAB has a powerful and flexible image display system which lets you use the imshow and plot commands to display complex images and then save the result. For example:
im = imread('image.tif');
f = figure, imshow(im, 'Border', 'tight');
rectangle('Position', [100, 100, 10, 10]);
print(f, '-r80', '-dtiff', 'image2.tif');
This works great.
The problem is that if you are doing a lot of image processing, it starts to be real drag to show every image you create - you mostly want to just save them. I know I could start directly writing to an image and then saving the result. But using plot/rectangle/imshow is so easy, so I'm hoping there is a command that can let me call plot, imshow etc, not display the results and then save what would have been displayed. Anyone know any quick solutions for this?
Alternatively, a quick way to put a spline onto a bitmap might work...
When you create the figure you set the Visibile property to Off.
f = figure('visible','off')
Which in your case would be
im = imread('image.tif');
f = figure('visible','off'), imshow(im, 'Border', 'tight');
rectangle('Position', [100, 100, 10, 10]);
print(f, '-r80', '-dtiff', 'image2.tif');
And if you want to view it again you can do
set(f,'visible','on')
The simple answer to your question is given by Bessi and Mr Fooz: set the 'Visible' setting for the figure to 'off'. Although it's very easy to use commands like IMSHOW and PRINT to generate figures, I'll summarize why I think it's not necessarily the best option:
As illustrated by Mr Fooz's answer, there are many other factors that come into play when trying to save figures as images. The type of output you get is going to be dependent on many figure and axes settings, thus increasing the likelihood that you will not get the output you want. This could be especially problematic if you have your figures set to be invisible, since you won't notice some discrepancy that could be caused by a change in a default setting for the figure or axes. In short, your output becomes highly sensitive to a number of settings that you would then have to add to your code to control your output, as Mr Fooz's example shows.
Even if you're not viewing the figures as they are made, you're still probably making MATLAB do more work than is really necessary. Graphics objects are still created, even if they are not rendered. If speed is a concern, generating images from figures doesn't seem like the ideal solution.
My suggestion is to actually modify the image data directly and save it using IMWRITE. It may not be as easy as using IMSHOW and other plotting solutions, but I think it is more efficient and gives more robust and consistent results that are not as sensitive to various plot settings. For the example you give, I believe the alternative code for creating a black rectangle would look something like this:
im = imread('image.tif');
[r,c,d] = size(im);
x0 = 100;
y0 = 100;
w = 10;
h = 10;
x = [x0:x0+w x0*ones(1,h+1) x0:x0+w (x0+w)*ones(1,h+1)];
y = [y0*ones(1,w+1) y0:y0+h (y0+h)*ones(1,w+1) y0:y0+h];
index = sub2ind([r c],y,x);
im(index) = 0;
im(index+r*c) = 0;
im(index+2*r*c) = 0;
imwrite(im,'image2.tif');
I'm expanding on Bessi's solution here a bit. I've found that it's very helpful to know how to have the image take up the whole figure and to be able to tightly control the output image size.
% prevent the figure window from appearing at all
f = figure('visible','off');
% alternative way of hiding an existing figure
set(f, 'visible','off'); % can use the GCF function instead
% If you start getting odd error messages or blank images,
% add in a DRAWNOW call. Sometimes it helps fix rendering
% bugs, especially in long-running scripts on Linux.
%drawnow;
% optional: have the axes take up the whole figure
subplot('position', [0 0 1 1]);
% show the image and rectangle
im = imread('peppers.png');
imshow(im, 'border','tight');
rectangle('Position', [100, 100, 10, 10]);
% Save the image, controlling exactly the output
% image size (in this case, making it equal to
% the input's).
[H,W,D] = size(im);
dpi = 100;
set(f, 'paperposition', [0 0 W/dpi H/dpi]);
set(f, 'papersize', [W/dpi H/dpi]);
print(f, sprintf('-r%d',dpi), '-dtiff', 'image2.tif');
If you'd like to render the figure to a matrix, type "help #avifile/addframe", then extract the subfunction called "getFrameForFigure". It's a Mathworks-supplied function that uses some (currently) undocumented ways of extracting data from figure.
Here is a completely different answer:
If you want an image file out, why not just save the image instead of the entire figure?
im = magic(10)
imwrite(im/max(im(:)),'magic.jpg')
Then prove that it worked.
imshow('magic.jpg')
This can be done for indexed and RGB also for different output formats.
You could use -noFigureWindows to disable all figures.