How to store image from cam? - opencv

I am just started with processing.js.
The goal of my program is adept image filter(opencv) to video frame.
So I thought (However I found out it does not working in this way :<) :
get video steam from Capture object which in processing.video package.
Store current Image(I hope it can store as PImage Object).
adept OpenCV image Filter
call image method with filtered PImage Object.
I found out how to get video stream from cam, but do not know how to store this.
import processing.video.*;
import gab.opencv.*;
Capture cap;
OpenCV opencv;
public void setup(){
//size(800, 600);
size(640, 480);
colorMode(RGB, 255, 255, 255, 100);
cap = new Capture(this, width, height);
opencv = new OpenCV(this, cap);
cap.start();
background(0);
}
public void draw(){
if(cap.available()){
//return void
cap.read();
}
image(cap, 0, 0);
}
this code get video stream and show what it gets. However, I can not store single frame since Capture.read() returns 'void'.
After Store current frame I would like to transform PImage s with OpenCV like :
PImage gray = opencv.getSnapshot();
opencv.threshold(80);
thresh = opencv.getSnapshot();
opencv.loadImage(gray);
opencv.blur(12);
blur = opencv.getSnapshot();
opencv.loadImage(gray);
opencv.adaptiveThreshold(591, 1);
adaptive = opencv.getSnapshot();
Is there any decent way to store and transform current frame? (I think my way - this means show frame after save current image and transform - uses lots of resources depend on frame rate)
Thanks for answer :D

not sure what you want to do, I'm sure you solved it already, but this could be useful for someone anyway...
It seems you can just write the Capture object's name directly and it returns a PImage:
cap = new Capture(this, width, height);
//Code starting and reading capture in here
PImage snapshot = cap;
//Then you can do whatever you wanted to do with the PImage
snapshot.save("snapshot.jpg");
//Actually this seems to work fine too
cap.save("snapshot.jpg");

Use opencv.loadImage(cap). For example:
if (cap.available() == true) {
cap.read();
}
opencv.loadImage(cap);
opencv.blur(15);
image(opencv.getSnapshot(), 0, 0);
Hope this helps!

Related

How Can I Detect Any Object from Video Camera in IOS?

I am developing an application to identify object from the real world object. Is that possible to identify any object from video camera? Now on words I am using openCV library to identify object. But just recording a video it does not do anything. I am very poor about AR. Please suggest me what I have to do for the identifying a real world object if possible.
Step 1: follow this to setup your opencv camera
Step 2: add this code to processImage delegate
- (void)processImage:(cv::Mat&)image
{
//process here
cv::cvtColor(image, img, cv::COLOR_BGRA2RGB);
int fixedWidth = 270;
cv::resize(img, img, cv::Size(fixedWidth,(int)((fixedWidth*1.0f)* (image.rows/(image.cols*1.0f)))),cv::INTER_NEAREST);
//update the model
bg_model->apply(img, fgmask, update_bg_model ? -1 : 0);
GaussianBlur(fgmask, fgmask, cv::Size(7, 7), 2.5, 2.5);
threshold(fgmask, fgmask, 10, 255, cv::THRESH_BINARY);
image = cv::Scalar::all(0);
img.copyTo(image, fgmask);
}
You'll need to declare following as global variable
cv::Mat img, fgmask;
cv::Ptr<cv::BackgroundSubtractor> bg_model;
bool update_bg_model;
Where, img <- smaller image fgmask <- the mask denotes that where motion is happening update_bg_model <- if you want to fixed your background;
for more detail go through this link

OpenCV and Windows 10 transparent image

Suppose we have the following color:
const Scalar TRANSPARENT2 = Scalar(255, 0, 255,0);
which is magenta but fully transparent: alpha = 0 (to be fully opaque is 255).
Now I made the following test based on:
http://blogs.msdn.com/b/lucian/archive/2015/12/04/opencv-first-version-up-on-nuget.aspx
WriteableBitmap^ Grabcut::TestTransparent()
{
Mat res(400,400, CV_8UC4);
res.setTo(TRANSPARENT2);
WriteableBitmap^ wbmp = ref new WriteableBitmap(res.cols, res.rows);
IBuffer^ buffer = wbmp->PixelBuffer;
unsigned char* dstPixels;
ComPtr<IBufferByteAccess> pBufferByteAccess;
ComPtr<IInspectable> pBuffer((IInspectable*)buffer);
pBuffer.As(&pBufferByteAccess);
pBufferByteAccess->Buffer(&dstPixels);
memcpy(dstPixels, res.data, res.step.buf[1] * res.cols * res.rows);
return wbmp;
}
The issue I have is that the image created is not fully transparent, it has a bit of alpha:
I understand there is a fila in the memcpy data, but I am not really sure about how to solve this. any idea to get it to alpha 0?
more details
To see I saving the image could then read and test if it works, I saw that the imwrite contains an snippet about transparency like in the image, but well imwrite is not implemented yet. But the transparency method is not working neither.
Any light with this snippet?
Thanks.
Finally I did the conversion in the C# code, first avoid calling CreateAlphaMat.
Then what I did is use a BitmapEncoder to convert data:
WriteableBitmap wb = new WriteableBitmap(bitmap.PixelWidth, bitmap.PixelHeight);
using (IRandomAccessStream stream = new InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
Stream pixelStream = bitmap.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied,
(uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, pixels);
await encoder.FlushAsync();
wb.SetSource(stream);
}
this.MainImage.Source = wb;
where bitmap is the WriteableBitmap from the OpenCV result. And now the image is fully transparent.
NOTE: Do not use MemoryStream and then .AsRandomAccessStream because it won't FlushAsync

how to detect moving object in live video camera using openCV

i am using openCV for my ios application to detect moving object in live video camera, but i am not familiar with use of openCV please help me. any other way to do this also welcome .
- (void)viewDidLoad {
[super viewDidLoad];
self.videoCamera.delegate = self;
self.videoCamera = [[CvVideoCamera alloc] initWithParentView:self.view];
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset352x288;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
self.videoCamera.grayscaleMode = NO;
[self.videoCamera start];
// cv::BackgroundSubtractorMOG2 bg;
}
- (void)processImage:(cv::Mat&)image
{
//process here
cv::cvtColor(image, img, cv::COLOR_BGRA2RGB);
int fixedWidth = 270;
cv::resize(img, img, cv::Size(fixedWidth,(int)((fixedWidth*1.0f)* (image.rows/(image.cols*1.0f)))),cv::INTER_NEAREST);
//update the model
bg_model->operator()(img, fgmask, update_bg_model ? -1 : 0);
GaussianBlur(fgmask, fgmask, cv::Size(7, 7), 2.5, 2.5);
threshold(fgmask, fgmask, 10, 255, cv::THRESH_BINARY);
image = cv::Scalar::all(0);
img.copyTo(image, fgmask);
}
i am new at openCV so, i don't know what to do.
Add this code to processImage delegate :
- (void)processImage:(cv::Mat&)image
{
//process here
cv::cvtColor(image, img, cv::COLOR_BGRA2RGB);
int fixedWidth = 270;
cv::resize(img, img, cv::Size(fixedWidth,(int)((fixedWidth*1.0f)* (image.rows/(image.cols*1.0f)))),cv::INTER_NEAREST);
//update the model
bg_model->apply(img, fgmask, update_bg_model ? -1 : 0);
GaussianBlur(fgmask, fgmask, cv::Size(7, 7), 2.5, 2.5);
threshold(fgmask, fgmask, 10, 255, cv::THRESH_BINARY);
image = cv::Scalar::all(0);
img.copyTo(image, fgmask);
}
You'll need to declare following as global variable
cv::Mat img, fgmask;
cv::Ptr<cv::BackgroundSubtractor> bg_model;
bool update_bg_model;
Where, img <- smaller image fgmask <- the mask denotes that where motion is happening update_bg_model <- if you want to fixed your background;
Please refer this URL for further information.
I am assuming that you are wanting something of a similar nature to this demonstration: https://www.youtube.com/watch?v=UFIVCDDnrmM
This gives you motion and removes the background of an image.
Anytime you are wanting to detect motion you often times must start by determining what is moving and what it still. This task is completed by taking several frames, and comparing them to determine if sections are different enough to be regarded as not being in the background. (Generally over a certain threshold of consistency.)
For finding the background in an image, check out: http://docs.opencv.org/master/d1/dc5/tutorial_background_subtraction.html
Afterwords you will need an implementation (potentially an edge detector like canny) to be able to recognize the object you are wanting and track its motion. (Determine velocity, direction, etc.) This will be specific to your use-case, and there isn't enough information in the original question to say specifically what you need here.
Another really good resource to look at would be: http://www.intorobotics.com/how-to-detect-and-track-object-with-opencv/
This even has a section dedicated to utilizing mobile devices with opencv. (The use scenario that they are using is robotics, one of the largest applications of computer vision, but you should be able to use it for what you need; albeit with a few modifications. )
Please let me know if this helps, and if I can do anything else to assist you.

get Original image from ROI image in opencv

is it possible to get back original image from image ROI? for example say we have
cv::Mat image = imread("image.jpg", 0);
cv::Mat imageROI = image(0, 0, 100, 100);
myFunction(imageROI);
and in myFunction I want to work with original image. is there any way to convert imageROI to original image when we don't access the original image?
I don't know if I understood the question exactly like you think, but if you ask if let's say we have header
void myFunc(cv::Mat &m);
// .... later on
cv::Mat image = imread("image.jpg", 0);
cv::Mat imageROI = image(0, 0, 100, 100);
myFunction(imageROI);
// .... later on myFuncDefinition
void myFunc(cv::Mat &m) {
// some code
// here you would like to have an original image, right?
}
So the answer for that is no and the proof is by simplicity: why want you to design opencv api in such way to make it possible store unnecessary data? If you do
cv::Mat imageROI = image(0, 0, 100, 100);
by purpose you would like to forgot about entire image and you are particulary interested in some ROI. Mat container is designed in such way to copy only matrix 'headers' and not matrix content. So if you do cv::Mat imageROI = image(0, 0, 100, 100) perhaps the matrix content (ie image data) might be stored somewhere in memory (because roi is the part of it, so by optimalization purposes it might no be deleted even is original image variable went out of scope), but your matrix header changed. Namely, from pointing to (0, 0, imageWisth, imageHeight) to (0, 0, 100, 100) and there's no way to bring it back just using variable m.
Why don't pass additional parameter as a reference?
Just incase anybody looks at this question you can actually do this
cv::Mat mat = ...
cv::Size size;
cv::Point offset;
// find original image size, and get offset of roi
mat.locateROI(size, offset);
// put image back to original size;
mat.adjustROI(offset.y, size.height - mat.rows, offset.x, size.width- mat.cols);

cvResizeWindow() flicker reaction

I have an OpenCV window that I would like to resize to fill my screen, but when I use the resize function the window flickers. The output is my webcam and I guess the flicker is because my camera does not have those dimensions. Is there any other way to make the output from the camera larger?
cvNamedWindow("video", CV_WINDOW_AUTOSIZE);
IplImage *frame=0;
frame=cvQueryFrame(capture);
cvShowImage("video", frame);
cvResizeWindow("video", 1920,1080);
Give you an example of using cvResize() to resize the image or frame.
IplImage *frame;
CvCapture *capture = cvCaptureFromCAM(0);
cvNamedWindow("capture", CV_WINDOW_AUTOSIZE);
while(1) {
frame = cvQueryFrame(capture);
IplImage *frame_resize = cvCreateImage(cvSize(1366, 768), frame -> depth, frame -> nChannels);
cvResize(frame, frame_resize, CV_INTER_LINEAR);
cvShowImage("capture", frame);
cvWaitKey(25);
}
One possibility is to use the cvResize() function to change the size of the frame.
However, an easier way is to get rid of the CV_WINDOW_AUTOSIZE flag -- without that the video will be displayed at the size of the window.
Something like this:
cvNamedWindow("video", 0);
cvResizeWindow("video", 1920,1080);
IplImage *frame=0;
while(true)
{
frame=cvQueryFrame(capture);
cvShowImage("video", frame);
int c = waitKey(10);
...
}
I am not sure of the cause of the flickering, as I could not replicate that issue on my system.
Therefore I cannot guarantee that the flickering will disappear for you (but at least the video should be the correct size).

Resources