I have problem when connect IP of camera like http://192.168.1.101.
I've seen in emgu document the url must like:
Capture cap = new Capture("rtsp://username:password#[IP Address]/mpeg4/media.amp");
But my camera use in LAN.
How to connect camera with IP http://? If it impossible, I hope anybody can say any solution for that.
Like convert http:// protocol to rtsp:// protocol.
Thank you very much!!!
One thing I would suggest is make sure you are using Emgu CV V3 not any of the lower versions.
If you are using it in lan it will still have an IP address and an RTSP port,
All I type in for my camera is:
Capture cap = new Capture("rtsp://username:password#cameraIP:RtspPort");
cap.ImageGrabbed += ProcessFrame;
cap.Start();
Then my ProcessFrame looks like this:
private void ProcessFrame(object sender, EventArgs e)
{
Mat image = new Mat();
_capture.Retrieve(image);
imageBox1.BackgroundImage = image.Bitmap;
}
Related
Let's say I have a wireless camera that I want to stream footage from to unity in real-time. Is there a way to achieve this?
Bonus questions:
What about cameras with wider angles (180, perhaps even 360)
How much of an issue would the delay be if this is a footage I want to be interacting with
Possible to send more data such as depth perception(using depth perception camera) aside from the regular footage only?
Am I crazy or has this been done?
Thanks in advance
I assume this is a camera with Ethernet port or Wi-Fi that you can connect to and stream images from it live.
If so, then yes, it can be done with Unity.
How it is done without an external library:
Connecting to the Camera:
1.Connect to the-same local network with the camera or if unpn is supported, you can also connect to it through internet. Usually, you need the IP and the port of the camera to do this. Let's say that the Camera IP Address is 192.168.1.5 and the port number is 900. The url to connect to is http://192.168.1.5:900.
Sometimes, it is simply an url that ends with .mjpg or .bin such as http://192.168.1.5/mjpg/video.mjpg and http://192.168.1.5/mjpg/video.bin
Every camera is different. The only way to find the url is to read its manual. If the manual is not available, connect to it with its official Application then use Wireshark to discover the url of the camera Image. The username and the password(if required) can also be found in the manual. If not available, google the model number and everything you need should be found.
Extracting the JPEG from the Camera:
When connected to the camera, the camera will be sending endless data to you. This data you can scan and retrieve the image from it.
2.Search for the JPEG header which is 0xFF followed by 0xD8. If these two bytes are next to each other then start reading the bytes and continue to save them to an array. You can use an index(int) variable to keep count of how many bytes you have received.
int counter = 0;
byte[] completeImageByte = new byte[500000];
byte[] receivedBytes = new byte[500000];
receivedBytes[counter] = byteFromCamera;
counter++;
3.While reading the data from the camera, check if the next two bytes is the JPEG footer which is 0xFF followed by 0xD9. If this is true then you have received the complete image(1 frame).
Your image bytes should look something like:
0xFF 0xD8 someotherbytes(thousands of them)..... then 0xFF 0xD9
Copy receivedBytes to the completeImageByte variable so that it can be used to display the image later on. Reset counter variable to 0.
Buffer.BlockCopy(receivedBytes, 0, completeImageByte, 0, counter);
counter = 0;
Displaying the JPEG Image to the Screen:
4.Display the Image to screen
Since you will be receiving many images per second, the most efficient way I found to display this is to use RawImage Component. So, don't use Image or Sprite Renderer for this if you want this to run on mobile devices.
public RawImage screenDisplay;
if(updateFrame){
Texture2D camTexture = new Texture2D(2, 2);
camTexture.LoadImage(completeImageByte);
screenDisplay.texture = camTexture;
}
You only need to do camTexture = new Texture2D(2, 2); once in the Start() function.
5.Jump back to step 2 and continue doing it until you want to quite.
API for connecting to the Camera:.
Use HttpWebRequest if the camera requires authentication (username and password).
For those that does not require authentication, use UnityWebRequest. When using UnityWebRequest, you must derive your own classes from DownloadHandlerScript or your app will crash as you will be receiving data non stop.
Example of deriving your own class from DownloadHandlerScript:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class CustomWebRequest : DownloadHandlerScript
{
// Standard scripted download handler - will allocate memory on each ReceiveData callback
public CustomWebRequest()
: base()
{
}
// Pre-allocated scripted download handler
// Will reuse the supplied byte array to deliver data.
// Eliminates memory allocation.
public CustomWebRequest(byte[] buffer)
: base(buffer)
{
}
// Required by DownloadHandler base class. Called when you address the 'bytes' property.
protected override byte[] GetData() { return null; }
// Called once per frame when data has been received from the network.
protected override bool ReceiveData(byte[] byteFromCamera, int dataLength)
{
if (byteFromCamera == null || byteFromCamera.Length < 1)
{
//Debug.Log("CustomWebRequest :: ReceiveData - received a null/empty buffer");
return false;
}
//Search of JPEG Image here
return true;
}
// Called when all data has been received from the server and delivered via ReceiveData
protected override void CompleteContent()
{
//Debug.Log("CustomWebRequest :: CompleteContent - DOWNLOAD COMPLETE!");
}
// Called when a Content-Length header is received from the server.
protected override void ReceiveContentLength(int contentLength)
{
//Debug.Log(string.Format("CustomWebRequest :: ReceiveContentLength - length {0}", contentLength));
}
}
Usage:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class Test : MonoBehaviour
{
CustomWebRequest camImage;
UnityWebRequest webRequest;
byte[] bytes = new byte[90000];
void Start()
{
string url = "http://camUrl/mjpg/video.mjpg";
webRequest = new UnityWebRequest(url);
webRequest.downloadHandler = new CustomWebRequest(bytes);
webRequest.Send();
}
}
You can them perform step 2,3,4 and 5 in the ReceiveData function from the CustomWebRequest script.
Controlling Camera:
Cameras have commands to pan, rotate, flip, mirror and perform other function.This is different in every camera but it is simple as making GET/POST request to a url of the camera and providing the queries. These commands can be found in the camera manual.
For example: http://192.168.1.5?pan=50&rotate=90
Other Frameworks:
AForge - A free framework that can handle both JPEG/MJPES and FFMPEG from the camera. You have to modify it to work with Unity and you should if you can't do step 2,3,4 and 5.
Nowadays I am using Honeywell IP camera for image processing application.But unfortunately I couldn't manage to open it using opencvsharp in c# programming.
So, I would like to share some part of my code and I am using ethernet cable to connect it directly(cable from my notebook to Ip camera).I defined static ip to my laptop and I am able to connect it using default ip configuration via internet explorer.But I am not able to connect and open this camera using c# programming.
I tried all relevant links to make it work as below.Any help would be highly apreciated.
string v2 = #"http://192.168.0.101:5060/h264";
CvCapture camera = new CvCapture(v2)
string v2 = #"http://admin:admin#192.168.0.101:564/h264";
string v2 = #"rtsp://admin:admin#192.168.0.101:564/h264";
string v2 = #"http://192.168.0.101:564/img/video.mjpeg";
string v2 = #"http://admin:admin#192.168.0.101:564/img/video.mjpeg";
string v2 = #"http://192.168.0.101:564/img/video.mjpeg";
string v2 = #"http://192.168.0.101:564/img/video.asf";
string v2 = #"http://192.168.0.101:564/img/video.mjpeg";
All these methods are defined according to related link below(I tried almost all but I couldn be successful
http://www.camera-sdk.com/p_183-how-to-connect-to-your-honeywell-ip-camera-onvif.html``
related image
You can use http://www.aforgenet.com/framework/docs/html/dbf7400d-fbe9-e770-57aa-f63bc507c917.htm JPGStream to capture your video.
_videoSource = new JPEGStream(ConnectionString);
_videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
_videoSource.Start();
And after capture you can process you images with opencv.
you can use ONVIF DEVICE MANAGER
then you can find the url of your ip camera
like:
rtsp://192.168.1.188/media?stream=0
Let's say I have a wireless camera that I want to stream footage from to unity in real-time. Is there a way to achieve this?
Bonus questions:
What about cameras with wider angles (180, perhaps even 360)
How much of an issue would the delay be if this is a footage I want to be interacting with
Possible to send more data such as depth perception(using depth perception camera) aside from the regular footage only?
Am I crazy or has this been done?
Thanks in advance
I assume this is a camera with Ethernet port or Wi-Fi that you can connect to and stream images from it live.
If so, then yes, it can be done with Unity.
How it is done without an external library:
Connecting to the Camera:
1.Connect to the-same local network with the camera or if unpn is supported, you can also connect to it through internet. Usually, you need the IP and the port of the camera to do this. Let's say that the Camera IP Address is 192.168.1.5 and the port number is 900. The url to connect to is http://192.168.1.5:900.
Sometimes, it is simply an url that ends with .mjpg or .bin such as http://192.168.1.5/mjpg/video.mjpg and http://192.168.1.5/mjpg/video.bin
Every camera is different. The only way to find the url is to read its manual. If the manual is not available, connect to it with its official Application then use Wireshark to discover the url of the camera Image. The username and the password(if required) can also be found in the manual. If not available, google the model number and everything you need should be found.
Extracting the JPEG from the Camera:
When connected to the camera, the camera will be sending endless data to you. This data you can scan and retrieve the image from it.
2.Search for the JPEG header which is 0xFF followed by 0xD8. If these two bytes are next to each other then start reading the bytes and continue to save them to an array. You can use an index(int) variable to keep count of how many bytes you have received.
int counter = 0;
byte[] completeImageByte = new byte[500000];
byte[] receivedBytes = new byte[500000];
receivedBytes[counter] = byteFromCamera;
counter++;
3.While reading the data from the camera, check if the next two bytes is the JPEG footer which is 0xFF followed by 0xD9. If this is true then you have received the complete image(1 frame).
Your image bytes should look something like:
0xFF 0xD8 someotherbytes(thousands of them)..... then 0xFF 0xD9
Copy receivedBytes to the completeImageByte variable so that it can be used to display the image later on. Reset counter variable to 0.
Buffer.BlockCopy(receivedBytes, 0, completeImageByte, 0, counter);
counter = 0;
Displaying the JPEG Image to the Screen:
4.Display the Image to screen
Since you will be receiving many images per second, the most efficient way I found to display this is to use RawImage Component. So, don't use Image or Sprite Renderer for this if you want this to run on mobile devices.
public RawImage screenDisplay;
if(updateFrame){
Texture2D camTexture = new Texture2D(2, 2);
camTexture.LoadImage(completeImageByte);
screenDisplay.texture = camTexture;
}
You only need to do camTexture = new Texture2D(2, 2); once in the Start() function.
5.Jump back to step 2 and continue doing it until you want to quite.
API for connecting to the Camera:.
Use HttpWebRequest if the camera requires authentication (username and password).
For those that does not require authentication, use UnityWebRequest. When using UnityWebRequest, you must derive your own classes from DownloadHandlerScript or your app will crash as you will be receiving data non stop.
Example of deriving your own class from DownloadHandlerScript:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class CustomWebRequest : DownloadHandlerScript
{
// Standard scripted download handler - will allocate memory on each ReceiveData callback
public CustomWebRequest()
: base()
{
}
// Pre-allocated scripted download handler
// Will reuse the supplied byte array to deliver data.
// Eliminates memory allocation.
public CustomWebRequest(byte[] buffer)
: base(buffer)
{
}
// Required by DownloadHandler base class. Called when you address the 'bytes' property.
protected override byte[] GetData() { return null; }
// Called once per frame when data has been received from the network.
protected override bool ReceiveData(byte[] byteFromCamera, int dataLength)
{
if (byteFromCamera == null || byteFromCamera.Length < 1)
{
//Debug.Log("CustomWebRequest :: ReceiveData - received a null/empty buffer");
return false;
}
//Search of JPEG Image here
return true;
}
// Called when all data has been received from the server and delivered via ReceiveData
protected override void CompleteContent()
{
//Debug.Log("CustomWebRequest :: CompleteContent - DOWNLOAD COMPLETE!");
}
// Called when a Content-Length header is received from the server.
protected override void ReceiveContentLength(int contentLength)
{
//Debug.Log(string.Format("CustomWebRequest :: ReceiveContentLength - length {0}", contentLength));
}
}
Usage:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class Test : MonoBehaviour
{
CustomWebRequest camImage;
UnityWebRequest webRequest;
byte[] bytes = new byte[90000];
void Start()
{
string url = "http://camUrl/mjpg/video.mjpg";
webRequest = new UnityWebRequest(url);
webRequest.downloadHandler = new CustomWebRequest(bytes);
webRequest.Send();
}
}
You can them perform step 2,3,4 and 5 in the ReceiveData function from the CustomWebRequest script.
Controlling Camera:
Cameras have commands to pan, rotate, flip, mirror and perform other function.This is different in every camera but it is simple as making GET/POST request to a url of the camera and providing the queries. These commands can be found in the camera manual.
For example: http://192.168.1.5?pan=50&rotate=90
Other Frameworks:
AForge - A free framework that can handle both JPEG/MJPES and FFMPEG from the camera. You have to modify it to work with Unity and you should if you can't do step 2,3,4 and 5.
I work on project that capture an images from webcams using C# and Aforge.
When the camera is a 'CyberLink' i get this frame from the camera:
The code that you see here is only part of my code of course, but it demonstrates my use in Aforge.
Get all cams on this PC:
var webCam = new FilterInfoCollection(FilterCategory.VideoInputDevice);
var cams = new List<VideoCaptureDevice>();
foreach (FilterInfo camInfo in webCam)
{
var cam = new VideoCaptureDevice(camInfo.MonikerString);
cam.NewFrame += NewFrameHandler;
cams.Add(cam);
}
I have a timer that every few minutes starts the camera like this:
foreach (var cam in cams)
{
cam.Start();
}
When i get the event 'NewFrame' i call to my function 'NewFrameHandler' to save the frame and close the camera:
var bit = (Bitmap)eventArgs.Frame.Clone();
bit.Save("#c:\Cam_" + DateTime.Now.Ticks + ".png", ImageFormat.Png);
foreach (var cam in cams)
{
cam.SignalToStop();
}
As i say the code works great, only when the camera is CyberLink i have this problem.
I removed the youcam software and now I get the frames properly.
Would love to hear if anyone has a more elegant solution.
The YouCam software may hijack the stream, and removing it may be the only option. You could also check if YouCam offers an API of its own that allows you to interface with the camera. I have used AForge before and it worked great with the Logitech cameras I was using. Your code looks good to me, though it was a year or two ago when I was using AForge.
I am currently working on a project where I need to simply display the users webcam on a
asp.image object. I am using the Aforge frame work and have gotten it to work on a windows app. In the windows app I would set up the video source variable equal to the image property of a picture box
In other words:
samplepicturebox1.image = videosource
The problem is, for asp there is only a asp:image object and the only property is .imageurl
imgSource.imageurl = ???
How would I go forth and link a video stream object to the image url or what other object would I use to display the stream? I have looked into putting an output on a seperate aspx.cs file so I could just use that as a imageurl but had no luck.
Here is my code to specify:
//using AForge.Video;
//using AForge.Video.DirectShow;
//using System.Drawing.Imaging;
public partial class WebForm1 : System.Web.UI.Page
{
private FilterInfoCollection VideoCaptureDevices;
private VideoCaptureDevice FinalVideo;
protected void Page_Load(object sender, EventArgs e)
{
drpSource.Items.Clear();
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo VideoCaptureDevice in VideoCaptureDevices)
{
drpSource.Items.Add(VideoCaptureDevice.Name);
}
drpSource.SelectedIndex = 0;
}
protected void btnStart_Click(object sender, EventArgs e)
{
FinalVideo = new VideoCaptureDevice(VideoCaptureDevices[drpSource.SelectedIndex].MonikerString);
FinalVideo.NewFrame +=new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}
void FinalVideo_NewFrame(object sender, NewFrameEventArgs deventArgs)
{
imgSource.ImageUrl=(FinalVideo.ToString());
}
}
I have also populated a combo box with the user's different video source. That also displays correctly
I really appreciate any help. This will translate into communications. I want to be able to stream between users just like Omegle and Chatroulette. If anyone would recommend a better framework to look into I'm open, I've only looked into Aforge and Touchless as two C# frameworks that support video streaming.
I've seen many use flash and I do know a bit of ActionScript, but to be completely honest, I'd rather not mess too much with flash as ActionScript is quite the pain and from my opinion in some aspects, flash slowly withering and dieing.
#KeithNicholas is correct. A web application is not the same as a client/winforms application. A web app is run in the webserver and not in the web browser.
It got no access to the user's webcam. You need to use a client side technology like flash or silverlight to be able to use the webcamera from the server.