How to show webcam captured through CanvasFrame on scene in javafx - opencv

I am working with opencv,javacv,javafx.
I want to show the captured webcam not on the CanvasFrame but on scene of my running application.
Here is the code of method which is capturing,
#FXML
void openWebcamOnBtnClick(ActionEvent event)
{
Thread thread=new Thread()
{
#Override
public void run()
{
//super.run(); //To change body of generated methods, choose Tools | Templates.
opencv_highgui.CvCapture capture=opencv_highgui.cvCreateCameraCapture(0);
opencv_highgui.cvSetCaptureProperty(capture, opencv_highgui.CV_CAP_PROP_FRAME_HEIGHT, 360);
opencv_highgui.cvSetCaptureProperty(capture, opencv_highgui.CV_CAP_PROP_FRAME_WIDTH, 640);
opencv_core.IplImage grabbedImage=opencv_highgui.cvQueryFrame(capture);
CanvasFrame frame=new CanvasFrame("Webcam");
frame.setCanvasSize(640, 360);
while(frame.isVisible() && (grabbedImage=opencv_highgui.cvQueryFrame(capture))!=null)
{
frame.showImage(grabbedImage);
}
opencv_highgui.cvReleaseCapture(capture);
grabbedImage.release();
//frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
}
};
thread.start();
}
By doing so , webcam starts capturing perfectly fine and shows it on CanvasFrame(On new Stage). but i want it to show on the old stage, whenever i click on the button "Open Webcam"" which is on the old stage.
Can i show the capturing webcam in ImageView or any pane??

Related

Unity 3d 2017.2.1 camera feed looks zoomed in iPad

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFeed : MonoBehaviour {
// Use this for initialization
public Renderer rend;
void Start () {
WebCamDevice[] devices = WebCamTexture.devices;
// for debugging purposes, prints available devices to the console
for(int i = 0; i < devices.Length; i++)
{
print("Webcam available: " + devices[i].name);
}
Renderer rend = this.GetComponentInChildren<Renderer>();
// assuming the first available WebCam is desired
WebCamTexture tex = new WebCamTexture(devices[0].name);
rend.material.mainTexture = tex;
//rend.material.SetTextureScale("tex", new Vector2(1.2f, 1.2f));
tex.Play();
}
// Update is called once per frame
void Update () {
}
}
I use the above code to render camera feed on a plane. The code works fine but I see zoomed feed(around 1.2x) when deployed to iPad. How can I get the normal feed. Or How do I zoom out the camera feed
According to https://answers.unity.com/questions/1421387/webcamtexture-zoomed-in-on-ipad-pro.html if you insert this code it should scale properly:
rend.material.SetTextureScale("_Texture", new Vector2(1f, 1f))
Furthermore, it seems that you were trying something like this but your vector was off (by 0.2f) though you have commented out that line as well. You could reduce the scale even more though that could make the image just smaller if the camera couldn't support that zoomout :).

How to start webcam capturing with javacv

I am new to JavaCV, i started to learn it but there is lack of documentation. so i need help. My goal in simple. Just take a capture with camera and open it in window, so i dont want to record or anything. Just open camera in window. this is my code:
public static void main(String[] args) throws FrameGrabber.Exception {
FrameGrabber grabber = FrameGrabber.createDefault(0);
grabber.start();
IplImage grabbedImage = converter.convert(grabber.grab());
CanvasFrame frame = new CanvasFrame("Some Title", CanvasFrame.getDefaultGamma()/grabber.getGamma());
while(grabber.grab()!=null){
frame.showImage(grabbedImage);
}
frame.dispose();
grabber.stop();
}
So what is bothering me is this: frame.showImage(grabbedImage);
What i need to do to get that image from camera
FrameGrabber grabber = FrameGrabber.createDefault(0);
grabber.start();
// Frame to capture
Frame frame = null;
CanvasFrame cFrame = new CanvasFrame("Some Title", CanvasFrame.getDefaultGamma()/grabber.getGamma());
while((frame = grabber.grab())!=null){
if (cFrame.isVisible())
{
cFrame.showImage(frame);
}
}

Can you Print a wxWindow in wxWidgets?

I am developing a program for windows using wxWidgets. I'm trying to implement a print function that will print a wxPanel (or wxWindow) to the printer. wxWidgets has a nice handy class that does this, if you draw into a DC.
Is there a way to get wxWidgets to draw a wxPanel or wxWindow in a DC?
I tried to use the HandlePrintClient (in response to a WM_PRINTCLIENT) function, but this just draws the background.
I also tried to create a printer DC and send it trough a similar function to HandlePrint, but the wxWidget stuff seems to be to tightly coupled with BeginPrint.
Is there some way to do what I want to do? Perhaps a class already written that will tack a wxScrolledWindow and send it to the printer? The window will have other controls and windows, like a wxGrid on it.
In the end, it is probably easier to draw what you want into the the printDC. However, with some care, you can use BLIT to copy what is displayed in your panel into the PrintDC without having to redraw everything.
So, in your override of the wxPrintout::OnPrintPage you can write something like this:
wxClientDC frameDC( wxGetApp().GetTopWindow() );
GetDC()->StretchBlit(0,0,5000,5000,
&frameDC, 0, 0, 500,500 );
This will copy everything displayed in your applications top level wondow into the printerDC.
The snag is that the print preview window tends to obliterate your top level frame contents when it pops up. If you have a large monitor and a small application window you can arrange things so they do not overlap
void MyFrame::OnPrint(wxCommandEvent& )
{
wxPrintPreview *preview = new wxPrintPreview(new MyPrintout(this), new MyPrintout(this));
wxPreviewFrame *frame = new wxPreviewFrame(preview, this,
"Demo Print Preview",
wxPoint(600, 100), // move preview window out of the way
wxSize(500, 500));
//frame->Centre(wxBOTH);
frame->Initialize();
frame->Show(true);
A better approach would be to BLIT the frame display into a memoryDC before popping up the print preview, then BLIT from the MemoryDC to the printerDC.
Something along these lines:
void MyFrame::OnPrint(wxCommandEvent& )
{
// save the display before it is clobbered by the print preview
static wxMemoryDC memDC;
static wxBitmap bitmap(500,500);
memDC.SelectObject( bitmap );
wxClientDC frameDC( wxGetApp().GetTopWindow() );
memDC.Blit(0,0,5000,5000,
&frameDC, 0, 0 );
wxPrintPreview *preview = new wxPrintPreview(new MyPrintout(memDC), new MyPrintout(memDC));
wxPreviewFrame *frame = new wxPreviewFrame(preview, this,
"Demo Print Preview",
wxPoint(600, 100), // move preview window out of the way
wxSize(500, 500));
frame->Centre(wxBOTH);
frame->Initialize();
frame->Show(true);
}
and then
class MyPrintout : public wxPrintout
{
wxMemoryDC & myMemDC;
public:
MyPrintout( wxMemoryDC & memDC)
: myMemDC( memDC )
{
}
bool OnPrintPage( int PageNum )
{
// copy saved dispay to printer DC
GetDC()->StretchBlit(0,0,5000,5000,
&myMemDC, 0, 0, 500,500 );
return true;
}
};

CaptureScreen() works, verified, but event PrintPage doesn't, am I missing something?

here is my code for printing. click print and dialog appears. if you click ok capture screenis initiated. Bitmap memoryImage becomes a bitmap of the current form is displaying. ive verified that it is correct and the image is captured succesfuly.
finally printDocument.Print() takes place. only prints one blank page. Ive tried changing it to e.Graphics.Color(Gray); and still no luck only prints a blank page.
obviously communication with printer is fine. My guess is that the page actually prints before the image is attatched, but ive never coded for printing before so im not sure how to rearange my code.
using System.Drawing.Printing;
//show print dialog (works great)
private void button2_Click(object sender, EventArgs e)
{
PrintDialog printDialog1 = new PrintDialog();
printDialog1.Document = printDocument1;
DialogResult result = printDialog1.ShowDialog();
if (result == DialogResult.OK)
{
CaptureScreen();
printDocument1.Print();
//this.Close();
}
}
Bitmap memoryImage;
//capture screen (works as well)
private void CaptureScreen()
{
Graphics myGraphics = this.CreateGraphics();
Size s = this.Size;
memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(
this.Location.X, this.Location.Y, 0, 0, s);
}
//drawimage from captured screen (doesn't work)
private void printDocument1_PrintPage(System.Object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(memoryImage, 0, 0);
}

how to dynamically change image source in a silverlight for windows phone 7 project?

I'm working on a windows phone 7 project, with silverlight, and i'm trying to show 4 images in sequence to give the user the feeling of a short movie.
I have 4 urls pointing to 4 different jpeg images, and I'm using an Image control to show these jpeg in sequence.
The way I'm trying to achieve this is by doing:
private void RetrieveImages()
{
image1.ImageOpened += new EventHandler<RoutedEventArgs>(image1_ImageOpened);
frameNumber = 0;
gotoNextImage();
}
void image1_ImageOpened(object sender, RoutedEventArgs e)
{
System.Threading.Thread.Sleep(400);
gotoNextImage();
}
private void gotoNextImage()
{
if (frameNumber < 4)
{
webBrowser1.Dispatcher.BeginInvoke(()=> {
image1.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(cam.framesUrl[frameNumber]));
frameNumber++;
});
}
else
{
image1.ImageOpened -= image1_ImageOpened;
}
}
But this just don't work as expected. I'm sure I'm missing something about how to interact with the UI.
Can anyone point me in the right direction?
Which is the best way to achieve this?
Edited:
I'll explain better what's wrong with my code... probably it's unclear what happens.
I don't get any error with my code, but I don't see the "movie effect" too. It just show 1 single image, without iterating between the image collection.
I think it's a threading problem... kind of I'm not doing the right thing in the right thread to see the UI updating as expected...
This seams to work best.
xaml
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="YourNamspace.YourClass"
d:DesignWidth="24"
d:DesignHeight="24">
<Grid x:Name="LayoutRoot">
<Image Name="YourImageName" Stretch="Fill" Source="YourPath" ImageOpened="onImageOpened"/>
</Grid>
</UserControl>
C#
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
namespace YourNameSpace
{
public partial class YourClass : UserControl
{
public int FirstImageIndex = 1;
public int LastImageIndex = 1000;
public int CurrentImageIndex = 1;
public YourClass()
{
InitializeComponent();
}
private void onImageOpened(object sender, System.Windows.RoutedEventArgs e)
{
Thread.Sleep(1000);
CurrentImageIndex = ( CurrentImageIndex == LastImageIndex ) ? FirstImageIndex : CurrentImageIndex++;
YourImageName.Source = new BitmapImage(new Uri("Your/path/to/image"+CurrentImageIndex+".jpg"), UriKind.RelativeOrAbsolute);
}
}
}
Hope that helps. I am pretty new to Silverlight.
So far the best way is to define the image as a resource. Via converter setting the image source.
But, your code should work fine as well. Try setting UriKind.RelativeOrAbsolute may be that should help. Because, this is the most common area while setting image source causes issue
HTH
Ok, I figured it out, and I think I also find a nice solution :) IMHO
I basically bound the Image.source to a proprerty of my class (that now extends INotifyPropertyChanged). But this gave me some issue about the transiction between images: since they were downloaded from internet there was a black images occurring between one images an the next one... but only the first time (i'm looping on a set of 4 images, looks like the video repeat), 'cause after that the images are cached.
So, what I've done is to cache the images the first time, without displaying the right Image control, but displaying instead another Image control (or whatever else) which says to the user "I'm loading".
For handle this scenario I've created a custom event:
public delegate void FramesPrefetchedEventHanlder();
public event FramesPrefetchedEventHanlder FramesPrefetched;
Now let's take a look at the RetrieveImages method:
private void RetrieveImages()
{
frameNumber = 0;
currentCycle = 0;
// set e very short interval, used for prefetching frames images
timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
timer.Tick += (sender, e) => gotoNextImage();
// defines what is going to happen when the prefetching is done
this.FramesPrefetched += () =>
{
// hide the "wait" image and show the "movie" one
imageLoading.Opacity = 0;
image1.Opacity = 1;
// set the timer with a proper interval to render like a short movie
timer.Interval = new TimeSpan(0, 0, 0, 0, 400);
};
// when a frame is loaded in the main Image control, the timer restart
image1.ImageOpened += (s, e) =>
{
if (currentCycle <= cycles) timer.Start();
};
// start the loading (and showing) frames images process
gotoNextImage();
}
Ok, now what we need to handle is the step by step loading of the image and communicate when we finished the prefetching phase:
private void gotoNextImage()
{
timer.Stop();
if (frameNumber < 4)
{
CurrentFrame = new System.Windows.Media.Imaging.BitmapImage(new Uri(cam.framesUrl[frameNumber]));
frameNumber++;
}
else
{
// repeat the frame's sequence for maxCycles times
if (currentCycle < maxCycles)
{
frameNumber = 0;
currentCycle++;
// after the first cycle through the frames, raise the FramesPrefetched event
if (currentCycle == 1)
{
FramesPrefetchedEventHanlder handler = FramesPrefetched;
if (handler != null) handler();
}
// step over to next frame
gotoNextImage();
}
}
}
This works pretty fine to me... but since I'm new to Silverlight and Windows Phone 7 developement, any suggestion for improvement is welcome.

Resources