Resize video source in OpenCV - java

i need to resize my webcam feed to a constant value like 430*315 to view from my j panel without resizing it only show a little area that is equal to the resized j panel um using OpenCV VideoCapture method for capture video from webcam
below is my code part that i used to do grab the frames
if (webSource.grab()) {
try {
webSource.retrieve(frame);
Graphics g = jPanel2.getGraphics();
i tried
Size sz = new Size(430, 315);
Imgproc.resize(frame, frame, sz);
and
webSource.set(CV_CAP_PROP_FRAME_WIDTH, 430);
webSource.set(CV_CAP_PROP_FRAME_HEIGHT, 315);
i was unable to accomplish my requirement from any of that so is there a way that this can be done

While Capturing Frames from the Webcam you can resize using the resizing function.
// Using C++
VideoCapture cap(0);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 430);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 315);
Mat image;
cap.read(image);
resize(image, image, Size(430, 315), 0, 0, INTER_CUBIC);
namedWindow("firstframe", 1);
imshow("firstframe", image);
waitKey(0);
Maybe this can do the trick.

To get sections of a current image as a new image, use ROI (region of interest) to specify the section. The ROI is a rectangle here, which can be initialized several ways.
Sorry this is in C++, not Java;
Some ways to specify the region:
Rect ROI = Rect(Point(0, 0), Size(430, 315));
Rect ROI = Rect(0, 0, 430, 315);
Rect ROI = Rect(Point(x, y), Point(x + 430, y + 315));
Now to get a section of the captured frame:
Mat windowedframe = frame(ROI);
WARNING: This method doesn't care if the boundaries of the rectangle is located in the image or not, so if you go beyond the resolution of frame, it will crash.

Related

Libgdx slider - drawables are drawn the wrong size

I am drawing a slider with Libgdx using the following code:
Pixmap pix = new Pixmap(200, 50, Pixmap.Format.RGBA8888);
pix.setColor(Color.BLACK);
pix.fill();
skin.add("sliderBackS", new Texture(pix));
Pixmap pix1 = new Pixmap(10, 70, Pixmap.Format.RGBA8888);
pix1.setColor(Color.RED);
pix1.fill();
skin.add("knobS", new Texture(pix1));
Slider.SliderStyle sliderStyle = new Slider.SliderStyle();
sliderStyle.disabledBackground = skin.newDrawable("sliderBackS");
sliderStyle.disabledKnob = skin.newDrawable("knobS");
sliderStyle.background = skin.newDrawable("sliderBackS");
sliderStyle.knob = skin.newDrawable("knobS");
skin.add("sunSlider", sliderStyle);
sunlightSlider = new Slider(0, 100, 1, false, sliderStyle);
stage.addActor(sunlightSlider);
sunlightSlider.setBounds(300, 300, 100, 10);
sunlightSlider.setDisabled(true);
sunlightSlider.setDebug(true);
And then else where:
stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
stage.draw();
But for some reason the pixmaps in the slider seem to be drawn at their actual size. This can be seen in the following picture (the green line is what it should be, from the debug):
For some reason the width seems to be constrained by sunlightSlider.setBounds(300, 300, 100, 10); but the height does not.
I know that I could choose the pixmap size to what ever I need, but I want to use an image from file. If I use a big image, then it overflows the bounds similarly.
I want it to look like it is above, but constrained to the green rectangle.
What am I doing wrong?
A TextureRegionDrawable, which is what you've created with your newDrawable calls, by default has a minimum size that matches its original pixel dimensions. The minimum size of the Drawable prevents the Slider widget from drawing it as small as it would like to fit it into its own bounds. So you can reduce the minimum size:
sliderStyle.disabledBackground = skin.newDrawable("sliderBackS");
sliderStyle.disabledBackground.setMinWidth(0);
sliderStyle.disabledBackground.setMinHeight(0);
// and so on for other new drawables.
I'm not sure what your long term plans are, but typically you want all your skin's images to be part of a single Texture object so the SpriteBatch doesn't have to flush itself many times to draw your whole scene.
If for some reason you're not doing that, you can at least make all these solid color drawables use the same texture. It can simply be a one-pixel white texture that is shared by everything. Also, make sure you are disposing of the pixmap you use to create a texture, or you are leaking memory!
Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pix.setColor(Color.WHITE);
pix.fill();
Texture tex = new Texture(pix);
pix.dispose();
skin.add(tex, "white");
Drawable blackDrawable = skin.newDrawable("white", Color.BLACK);
Drawable redDrawable = skin.newDrawable("white", Color.RED);
Slider.SliderStyle sliderStyle = new Slider.SliderStyle();
sliderStyle.disabledBackground = blackDrawable;
sliderStyle.disabledKnob = redDrawable;
sliderStyle.background = blackDrawable;
sliderStyle.knob = redDrawable;
Since you passed your Texture object to the Skin, the Skin will dispose of it when the Skin is disposed. Don't forget to dispose of the Skin in the dipose() method.

How to resize an image in a panel with OpenImaj

I use OpenImaj for a project and I need to display the video in 800*600 to a panel but I must capture images at 1920,1080 when I click a button.
My strategy was initially to capture from my webcam at 1920,1080 and to resize image in a icon of a label contained in my panelVideo.
My problem is that the performance is very low.
Is there an efficient method to resize video according to the size of panelVideo without changing the frame size (that I use for saving the image at 1920,1080)?
Thank you for your answer.
Regards.
final VideoCapture vc = new VideoCapture(1920,1080);
vc.setFPS(10);
final VideoDisplay<MBFImage> display = VideoDisplay.createVideoDisplay(vc, panelVideo);
display.addVideoListener(new VideoDisplayAdapter<MBFImage>()
{
#Override
public void beforeUpdate(final MBFImage frame)
{
//here I create a bufferedImage from the resized frame
BufferedImage img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
g.drawImage(ImageUtilities.createBufferedImageForDisplay(frame), 0, 0, 800, 600, null);
//here is the label that I use to display the video
labelVideo.setIcon(new ImageIcon(ImageUtilities.createBufferedImageForDisplay(frame)));
}
});
You can at least remove fixed code like this out of the loop - that is create it only once
//here I create a bufferedImage from the resized frame
BufferedImage img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
and also have the Icon created once and setImage() as needed. Beyond that I dont know how to convert MBF to BufferedImage thats the pain of using different libraries. g.drawImage() is a good way to draw the scaled image.
See http://openimaj.org/apidocs/org/openimaj/image/processing/resize/package-frame.html for the OpenIMAJ classes that let you resize an MBFImage. You'll have to play and see what is fastest, but in my very quick experiments I found BilinearInterpolation to be better than ResizeProcessor with the default options, however using a different filter in ResizeProcessor might be faster.
Rather than creating a new BufferedImage each frame, you would probably be better off drawing the MBFImage into a Swing component that displays them directly: http://openimaj.org/apidocs/org/openimaj/image/DisplayUtilities.ScalingImageComponent.html or http://openimaj.org/apidocs/org/openimaj/image/DisplayUtilities.ImageComponent.html (note that technically these both convert to BufferedImage behind the scenes, but they only allocate the image once and just redraw into it saving a lot of time).

OpenCV-removing noise from image

I'm working on a java image processing program(based on OpenCV library).
I need to remove the noise from the first image to get a clean image like the second image below.
In this specific case, what are the best ways to remove noise?
The most important part is how to remove the black parts that surround the image.
First image:
Second image:
get rid of gray: threshold the image so that any gray becomes white
get rid of border: floodfill at location (0.0) with white
That will leave just a few remaining issues to clean up: detect each black blob in the image, if the area of a blob is less than some amount floodfill the blob with white. One way to implement that follows.
Note that floodfill returns the number of pixels it filled. This allows you to scan for a black pixel, when you find one fill with gray. If the filled are is too small, fill again with white to erase the blob and then keep scanning, otherwise leave the blob as gray and keep scanning for black. At the end everything you want will be gray, so scan the image again and whenever you find gray flood fill with black.
Following program may be helpful to solve your problem,
This program thresholds the input image and selects only connected
components with particular size
#include <iostream>
#include<cv.h>
#include<highgui.h>
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
IplImage *img1 = cvLoadImage(argv[1] , 0);
IplImage *img3 = cvLoadImage(argv[1]);
IplImage *img2 = cvCloneImage(img1);
cvNamedWindow("Orig");
cvShowImage("Orig",img1);
cvWaitKey(0);
cvAdaptiveThreshold(img1, img1, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C,
CV_THRESH_BINARY_INV, 15);
cvNamedWindow("Thre");
cvShowImage("Thre",img1);
cvWaitKey(0);
IplImage *tempImg = cvCloneImage(img1);
CvMemStorage *storage = cvCreateMemStorage(0);
CvSeq *contour = NULL;
cvFindContours(tempImg, storage, &contour, sizeof(CvContour),
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
for (; contour != 0; contour = contour->h_next)
{
CvRect r = cvBoundingRect(contour);
int area = r.width * r.height;
if (area < 50 || area > 500) continue;
cvRectangle(img3, cvPoint(r.x, r.y), cvPoint(r.x + r.width, r.y + r.height),
CV_RGB(255, 0, 0), 1);
}
cvNamedWindow("D");
cvShowImage("D",img3);
cvWaitKey(0);
}

Getting transparency to work in Java

I am trying to rotate an image in Java, but when I do the transparency in the png goes away. Is there any way i can rotate the image AND keep the transparency?
AffineTransform trans = new AffineTransform();
trans.setTransform(identity);
trans.translate(100, 100);
trans.rotate( Math.toRadians(45) );
gr.drawImage(image.getImage(), trans, this);
This makes the transparency in the png black, but
gr.drawImage(image.getImage(), 0, 200, null);
Has no problem with the transparency.
Try to set rendering hints on Graphics2D object.
gr.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY );
Check reference for optimal settings.

BufferedImage colour change

I have working on an application which captures screen shots and create video from captured images. But the problem is that when video is generated, colours in generated video is very pinkish. I think this is because I am manipulating captured images to show cursor using BufferedImage.TYPE_3BYTE_BGR type. Could someone tell me how to resolve this issue, I want to have the colour of video same as actual colour of screen.
For capturing screen image I am doing as follows:
Robot robot = new Robot();
Rectangle captureSize = new Rectangle(screenBounds);
return robot.createScreenCapture(captureSize);
For manipulating images I am doing as follows:
image = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
if (true) {
int x = MouseInfo.getPointerInfo().getLocation().x - 25;
int y = MouseInfo.getPointerInfo().getLocation().y - 37;
Graphics2D graphics2D = sourceImage.createGraphics();`enter code here`
graphics2D.drawImage(SimpleWebBrowserExample.m_MouseIcon, x, y, 48, 48, null);
}
image.getGraphics().drawImage(sourceImage, 0, 0, null);
return image;
please tell me how to get the images with colour same as actual colour on screen.
Thanks.
Use BufferedImage.TYPE_INT_ARGB or BufferedImage.TYPE_INT_RGB, as shown in this example. If you need to change the colors, you can use a LookupOp with a four-component LookupTable that adjusts the alpha component as required for BufferedImage.TYPE_3BYTE_BGR: "When data with non-opaque alpha is stored in an image of this type, the color data must be adjusted to a non-premultiplied form and the alpha discarded." Examples may be found in Using the Java 2D LookupOp Filter Class to Process Images and Image processing with Java 2D.
See the the "pinkish" explanation here
Basically the image is saved as a ARGB and most viewers interpret it as a CMYK. Alpha is preserved when opening it back in Java, though.

Categories

Resources