OpenCV memory leak issue - memory-leaks

This function of drawItem is called multiple times through a loop, I'm facing a memory leak issue everytime it is called. I'm thinking that the problem is due to the resizeImage() function, but I can't seem to pinpoint the problem, this is C++\CLI with OpenCV library.
drawItem()
{
imgItem = resizeImage(imgItem, newItemWidth, newItemHeight, false);
imgMask = resizeImage(imgMask, newItemWidth, newItemHeight, false);
cvSetImageROI(image3, cvRect(x1,y1,newItemWidth, newItemHeight));
cvCopy(imgItem, image3, imgMask);
cvResetImageROI(image3);
cvReleaseImage( &imgItem );
cvReleaseImage( &imgMask );
}
IplImage* resizeImage(const IplImage *origImg, int newWidth, int newHeight, bool keepAspectRatio)
{
IplImage *outImg = 0;
int origWidth;
int origHeight;
if (origImg) {
origWidth = origImg->width;
origHeight = origImg->height;
}
if (newWidth <= 0 || newHeight <= 0 || origImg == 0
|| origWidth <= 0 || origHeight <= 0) {
//cerr << "ERROR: Bad desired image size of " << newWidth
// << "x" << newHeight << " in resizeImage().\n";
exit(1);
}
if (keepAspectRatio) {
// Resize the image without changing its aspect ratio,
// by cropping off the edges and enlarging the middle section.
CvRect r;
// input aspect ratio
float origAspect = (origWidth / (float)origHeight);
// output aspect ratio
float newAspect = (newWidth / (float)newHeight);
// crop width to be origHeight * newAspect
if (origAspect > newAspect) {
int tw = (origHeight * newWidth) / newHeight;
r = cvRect((origWidth - tw)/2, 0, tw, origHeight);
}
else { // crop height to be origWidth / newAspect
int th = (origWidth * newHeight) / newWidth;
r = cvRect(0, (origHeight - th)/2, origWidth, th);
}
IplImage *croppedImg = cropImage(origImg, r);
// Call this function again, with the new aspect ratio image.
// Will do a scaled image resize with the correct aspect ratio.
outImg = resizeImage(croppedImg, newWidth, newHeight, false);
cvReleaseImage( &croppedImg );
}
else {
// Scale the image to the new dimensions,
// even if the aspect ratio will be changed.
outImg = cvCreateImage(cvSize(newWidth, newHeight),
origImg->depth, origImg->nChannels);
if (newWidth > origImg->width && newHeight > origImg->height) {
// Make the image larger
cvResetImageROI((IplImage*)origImg);
// CV_INTER_LINEAR: good at enlarging.
// CV_INTER_CUBIC: good at enlarging.
cvResize(origImg, outImg, CV_INTER_LINEAR);
}
else {
// Make the image smaller
cvResetImageROI((IplImage*)origImg);
// CV_INTER_AREA: good at shrinking (decimation) only.
cvResize(origImg, outImg, CV_INTER_AREA);
}
}
return outImg;
}
IplImage* cropImage(const IplImage *img, const CvRect region)
{
IplImage *imageCropped;
CvSize size;
if (img->width <= 0 || img->height <= 0
|| region.width <= 0 || region.height <= 0) {
//cerr << "ERROR in cropImage(): invalid dimensions." << endl;
exit(1);
}
if (img->depth != IPL_DEPTH_8U) {
//cerr << "ERROR in cropImage(): image depth is not 8." << endl;
exit(1);
}
// Set the desired region of interest.
cvSetImageROI((IplImage*)img, region);
// Copy region of interest into a new iplImage and return it.
size.width = region.width;
size.height = region.height;
imageCropped = cvCreateImage(size, IPL_DEPTH_8U, img->nChannels);
cvCopy(img, imageCropped); // Copy just the region.
return imageCropped;
}

I've found out the problem, it is due to Multiple Memory Allocations.
imgItem was pointing to something earlier, but after i did
imgItem = resizeImage(imgItem, newItemWidth, newItemHeight, false);
imgItem now points to another thing, the memory created in when imgItem was created is lost forever, no variable points to it, hence a memory leak.
so i used tempImgItem to solve the problem,
tempImgItem = resizeImage(imgItem, newItemWidth, newItemHeight, false);
tempImgMask = resizeImage(imgMask, newItemWidth, newItemHeight, false);
cvReleaseImage( &imgItem );
cvReleaseImage( &imgMask );
imgItem = tempImgItem;
imgMask = tempImgMask;
tempImgItem = NULL;
tempImgMask = NULL;

I think it is because you call "resizeImage" in itself, and you forgot to release the outImage inside

Related

Index out of range exception while reading pixel data

Related post: Stride of the BitmapData is different than the original
dimension.
I have taken the source code from here and modified it.
The code is generating a variety of exceptions in different occasions.
.
Error in BitmapLocker.cs
At the following line in Lock(),
// Copy data from IntegerPointer to _imageData
Marshal.Copy(IntegerPointer, _imageData, 0, _imageData.Length);
The following exception is being generated:
An unhandled exception of type 'System.AccessViolationException'
occurred in mscorlib.dll
Additional information: Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.
For the following driver code,
double[,] mask = new double[,]
{
{ .11, .11, .11, },
{ .11, .11, .11, },
{ .11, .11, .11, },
};
Bitmap bitmap = ImageDataConverter.ToBitmap(mask);
BitmapLocker locker = new BitmapLocker(bitmap);
locker.Lock();
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
Color c = locker.GetPixel(i, j);
locker.SetPixel(i, j, c);
}
}
locker.Unlock();
At the following line in GetPixel(),
if (i > dataLength)
{
throw new IndexOutOfRangeException();
}
An unhandled exception of type 'System.IndexOutOfRangeException'
occurred in Simple.ImageProcessing.Framework.dll
Additional information: Index was outside the bounds of the array.
.
At the following line in SetPixel(),
if (ColorDepth == 8)
{
_imageData[i] = color.B;
}
An unhandled exception of type 'System.Exception' occurred in
Simple.ImageProcessing.Framework.dll
Additional information: (0, 0), 262144, Index was outside the bounds
of the array., i=262144
.
Error in Driver program
At the line,
Color c = bmp.GetPixel(i, j);
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.Drawing.dll
Additional information: Bitmap region is already locked.
Source Code:
public class BitmapLocker : IDisposable
{
//private properties
Bitmap _bitmap = null;
bool _isLocked = false;
BitmapData _bitmapData = null;
private byte[] _imageData = null;
//public properties
public IntPtr IntegerPointer { get; private set; }
public int Width { get { return _bitmap.Width; } }
public int Height { get { return _bitmap.Height; } }
public int Stride { get { return _bitmapData.Stride; } }
public int ColorDepth { get { return Bitmap.GetPixelFormatSize(_bitmap.PixelFormat); } }
public int Channels { get { return ColorDepth / 8; } }
public int PaddingOffset { get { return _bitmapData.Stride - (_bitmap.Width * Channels); } }
public PixelFormat ImagePixelFormat { get { return _bitmap.PixelFormat; } }
public bool IsGrayscale { get { return Grayscale.IsGrayscale(_bitmap); } }
//Constructor
public BitmapLocker(Bitmap source)
{
IntegerPointer = IntPtr.Zero;
this._bitmap = source;
}
/// Lock bitmap
public void Lock()
{
if (_isLocked == false)
{
try
{
// Lock bitmap (so that no movement of data by .NET framework) and return bitmap data
_bitmapData = _bitmap.LockBits(
new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
ImageLockMode.ReadWrite,
_bitmap.PixelFormat);
// Create byte array to copy pixel values
int noOfBitsNeededForStorage = _bitmapData.Stride * _bitmapData.Height;
int noOfBytesNeededForStorage = noOfBitsNeededForStorage / 8;
_imageData = new byte[noOfBytesNeededForStorage * ColorDepth];//# of bytes needed for storage
IntegerPointer = _bitmapData.Scan0;
// Copy data from IntegerPointer to _imageData
Marshal.Copy(IntegerPointer, _imageData, 0, _imageData.Length);
_isLocked = true;
}
catch (Exception)
{
throw;
}
}
else
{
throw new Exception("Bitmap is already locked.");
}
}
/// Unlock bitmap
public void Unlock()
{
if (_isLocked == true)
{
try
{
// Copy data from _imageData to IntegerPointer
Marshal.Copy(_imageData, 0, IntegerPointer, _imageData.Length);
// Unlock bitmap data
_bitmap.UnlockBits(_bitmapData);
_isLocked = false;
}
catch (Exception)
{
throw;
}
}
else
{
throw new Exception("Bitmap is not locked.");
}
}
public Color GetPixel(int x, int y)
{
Color clr = Color.Empty;
// Get color components count
int channels = ColorDepth / 8;
// Get start index of the specified pixel
int i = (Height - y - 1) * Stride + x * channels;
int dataLength = _imageData.Length - channels;
if (i > dataLength)
{
throw new IndexOutOfRangeException();
}
if (ColorDepth == 32) // For 32 bpp get Red, Green, Blue and Alpha
{
byte b = _imageData[i];
byte g = _imageData[i + 1];
byte r = _imageData[i + 2];
byte a = _imageData[i + 3]; // a
clr = Color.FromArgb(a, r, g, b);
}
if (ColorDepth == 24) // For 24 bpp get Red, Green and Blue
{
byte b = _imageData[i];
byte g = _imageData[i + 1];
byte r = _imageData[i + 2];
clr = Color.FromArgb(r, g, b);
}
if (ColorDepth == 8)
// For 8 bpp get color value (Red, Green and Blue values are the same)
{
byte c = _imageData[i];
clr = Color.FromArgb(c, c, c);
}
return clr;
}
public void SetPixel(int x, int y, Color color)
{
// Get color components count
int cCount = ColorDepth / 8;
// Get start index of the specified pixel
int i = ((Height - y -1) * Stride + x * cCount);
try
{
if (ColorDepth == 32) // For 32 bpp set Red, Green, Blue and Alpha
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
_imageData[i + 3] = color.A;
}
if (ColorDepth == 24) // For 24 bpp set Red, Green and Blue
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
}
if (ColorDepth == 8)
// For 8 bpp set color value (Red, Green and Blue values are the same)
{
_imageData[i] = color.B;
}
}
catch(Exception ex)
{
throw new Exception("("+x+", "+y+"), "+_imageData.Length+", "+ ex.Message+", i=" + i);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
_bitmap = null;
_bitmapData = null;_imageData = null;IntegerPointer = IntPtr.Zero;
}
// free native resources if there are any.
//private properties
//public properties
}
}
.
ImageDataConverter.cs
public static Bitmap ToBitmap(double[,] input)
{
int width = input.GetLength(0);
int height = input.GetLength(1);
Bitmap output = Grayscale.CreateGrayscaleImage(width, height);
BitmapData data = output.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly,
output.PixelFormat);
int pixelSize = System.Drawing.Image.GetPixelFormatSize(PixelFormat.Format8bppIndexed) / 8;
int offset = data.Stride - width * pixelSize;
double Min = 0.0;
double Max = 255.0;
unsafe
{
byte* address = (byte*)data.Scan0.ToPointer();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
double v = 255 * (input[x, y] - Min) / (Max - Min);
byte value = unchecked((byte)v);
for (int c = 0; c < pixelSize; c++, address++)
{
*address = value;
}
}
address += offset;
}
}
output.UnlockBits(data);
return output;
}
Here is the picture I used for the test,
int noOfBitsNeededForStorage = _bitmapData.Stride * _bitmapData.Height;
That is the most essential bug in the code. Stride * Height are the number of bytes needed for storage. So it doesn't make the _imageData array large enough and IndexOutOfRangeException is the expected outcome.
int pixelSize = System.Drawing.Image.GetPixelFormatSize(PixelFormat.Format8bppIndexed) / 8;
Lots of possible mishaps from this statement. It hard-codes the pixel format to 8bpp but that is not the actual pixel format that the LockBits() call used. Which was output.PixelFormat. Notably fatal on the sample image, although it is not clear how it is used in the code, 8bpp is a very awkward pixel format since it requires a palette. The PNG codec will create a 32bpp image in memory, even though the original file uses 8bpp. You must use output.PixelFormat here to get a match with the locked data and adjust the pixel writing code accordingly. Not clear why it is being used at all, the SetPixel() method provided by the library code should already be good enough.
int dataLength = _imageData.Length - channels;
Unclear what that statement tries to do, subtracting the number of channels is not a sensible operation. It will generate a spurious IndexOutOfRangeException. There is no obvious reason to help, the CLR already provides array index checking on the _imageData array. So just delete that code.
Additional information: Bitmap region is already locked.
Exception handling in the code is not confident, a possible reason for this exception. In general it must be noted that the underlying bitmap is completely inaccessible, other than through _imageData, after the Lock() method was called and Unlock() wasn't called yet. Best way to do this is with try/finally with the Unlock() call in the finally block so you can always be sure that the bitmap doesn't remain locked by accident.
byte c = _imageData[i];
This is not correct, except in the corner case of an 8bpp image that has a palette that was explicitly created to handle grayscale images. The default palette for an 8bpp image does not qualify that requirement nor is it something you can blindly rely on when loading images from a file. Indexed pixel formats where a dreadful hack that was necessary in the early 1990s because video adapters where not yet powerful enough. It no longer makes any sense at all today. Note that SetPixel() also doesn't handle a 16-bit pixel formats. And that the PNG codec will never create an 8bpp memory image and cannot encode an 8bpp file. Best advice is to eliminate 8bpp support completely to arrive at more reliable code.
In fact, the point of directly accessing pixel data is to make image manipulation fast. There is only one pixel format that consistently produces fast code, it is Format32bppArgb. The pixels can now be accessed with an int* instead of a byte*, moving pixels ~4 times faster. And no special tweaks are necessary to deal with stride or special-case the code for methods like SetPixel(). So pass that format into LockBits(), the codec will do the work necessary if the actual image format is not 32bpp as well.
I should note that Format32bppPArgb is the fast pixel format for displaying images on the screen since it is compatible with the pixel format used by all modern video adapters. But that isn't the point of this code and dealing with the pre-multiplied alpha is awkward.

Rotate a image in c++

Hi I am very new to c++.
Image im(L"C:\\Temp\\SnapShotOutput.jpg");
im.RotateFlip(Rotate90FlipNone);
im.Save("SampleImage_rotated.jpg");
I am trying to above code to rotate a image and save...
It wont work .compile fail at the 3rd line
'Gdiplus::Image::Save' : no overloaded function takes 1 arguments
it gives the above error.
can anybody help me.
You should set other parameters too. Code is from here.
Image image(L"C:\\Temp\\SnapShotOutput.jpg");
image.RotateFlip(Rotate90FlipNone);
// Save the altered image as PNG
CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
image.Save(L"SampleImage_rotated.png", &pngClsid, NULL);
// Save the altered image as JPG
CLSID jpegClsid;
GetEncoderClsid(L"image/jpeg", &jpegClsid);
image.Save(L"SampleImage_rotated.jpg", &jpegClsid, NULL);
The GetEncoderClsid function is defined here:
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}

Out of memory error native Image decode Error while loading image to gallery

I am trying to load image from a folder into my application, the code I am using is
FileConnection fc = null;
DataInputStream in = null;
DataOutputStream out = null;
try {
fc = (FileConnection)Connector.open("file:///e:/Images/Abc.jpg");
int length = (int)fc.fileSize();//possible loss of precision may throw error
byte[] data = null;
if (length != -1) {
data = new byte[length];
in = new DataInputStream(fc.openInputStream());
in.readFully(data);
}
else {
int chunkSize = 112;
int index = 0;
int readLength = 0;
in = new DataInputStream(fc.openInputStream());
data = new byte[chunkSize];
do {
if (data.length < index + chunkSize) {
byte[] newData = new byte[index + chunkSize];
System.arraycopy(data, 0, newData, 0, data.length);
data = newData;
}
readLength = in.read(data, index, chunkSize);
index += readLength;
} while (readLength == chunkSize);
length = index;
}
Image image = Image.createImage(data, 0, length);
image = createThumbnail(image);
ImageItem imageItem = new ImageItem(null, image, 0, null);
mForm.append(imageItem);
mForm.setTitle("Done.");
fc = (FileConnection)Connector.open("file:///e:/Images/Abc.jpg");
if(!fc.exists()){
try{
fc.create();
}catch(Exception ce){System.out.print("Create Error: " + ce);}
}
out = new DataOutputStream(fc.openOutputStream());
out.write(data);
}
catch (IOException ioe) {
StringItem stringItem = new StringItem(null, ioe.toString());
mForm.append(stringItem);
mForm.setTitle("Done.");
}
finally {
try {
if (in != null) in.close();
if (fc != null) fc.close();
}
catch (IOException ioe) {}
hope it can be the problem with image I tried to resize the image
private Image createThumbnail(Image image)
{
int sourceWidth = image.getWidth();
int sourceHeight = image.getHeight();
int thumbWidth = 18;
int thumbHeight = 23;
Image thumb = Image.createImage(thumbWidth, thumbHeight);
Graphics g = thumb.getGraphics();
for (int y = 0; y < thumbHeight; y++)
{
for (int x = 0; x < thumbWidth; x++)
{
g.setClip(x, y, 1, 1);
int dx = x * sourceWidth / thumbWidth;
int dy = y * sourceHeight / thumbHeight;
g.drawImage(image, x - dx, y - dy, Graphics.LEFT | Graphics.TOP);
}
}
Image immutableThumb = Image.createImage(thumb);
return immutableThumb;
}
Still it returns an exception out of memmory native image deocde error, Somebody pls help me to sort it out
This may occur becuase of two reason.
Image size: In some phones due to small heap size not device does not load image so try with smaller image size.
Second reason may be image is corrupt so try with another image.

How To Convert C# Code into Android (Motion Detection )

public class MotionDetector1 : IMotionDetector
{
private IFilter grayscaleFilter = new GrayscaleBT709( );
private Difference differenceFilter = new Difference( );
private Threshold thresholdFilter = new Threshold( 15 );
private IFilter erosionFilter = new Erosion( );
private Merge mergeFilter = new Merge( );
private IFilter extrachChannel = new ExtractChannel( RGB.R );
private ReplaceChannel replaceChannel = new ReplaceChannel( RGB.R, null );
private Bitmap backgroundFrame;
private BitmapData bitmapData;
private bool calculateMotionLevel = false;
private int width; // image width
private int height; // image height
private int pixelsChanged;
// Motion level calculation - calculate or not motion level
public bool MotionLevelCalculation
{
get { return calculateMotionLevel; }
set { calculateMotionLevel = value; }
}
// Motion level - amount of changes in percents
public double MotionLevel
{
get { return (double) pixelsChanged / ( width * height ); }
}
// Constructor
public MotionDetector1( )
{
}
// Reset detector to initial state
public void Reset( )
{
if ( backgroundFrame != null )
{
backgroundFrame.Dispose( );
backgroundFrame = null;
}
}
// Process new frame
public void ProcessFrame( ref Bitmap image )
{
if ( backgroundFrame == null )
{
// create initial backgroung image
backgroundFrame = grayscaleFilter.Apply( image );
// get image dimension
width = image.Width;
height = image.Height;
// just return for the first time
return;
}
Bitmap tmpImage;
// apply the grayscale file
tmpImage = grayscaleFilter.Apply( image );
// set backgroud frame as an overlay for difference filter
differenceFilter.OverlayImage = backgroundFrame;
// apply difference filter
Bitmap tmpImage2 = differenceFilter.Apply( tmpImage );
// lock the temporary image and apply some filters on the locked data
bitmapData = tmpImage2.LockBits( new Rectangle( 0, 0, width, height ),
ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed );
// threshold filter
thresholdFilter.ApplyInPlace( bitmapData );
// erosion filter
Bitmap tmpImage3 = erosionFilter.Apply( bitmapData );
// unlock temporary image
tmpImage2.UnlockBits( bitmapData );
tmpImage2.Dispose( );
// calculate amount of changed pixels
pixelsChanged = ( calculateMotionLevel ) ?
CalculateWhitePixels( tmpImage3 ) : 0;
// dispose old background
backgroundFrame.Dispose( );
// set backgound to current
backgroundFrame = tmpImage;
// extract red channel from the original image
Bitmap redChannel = extrachChannel.Apply( image );
// merge red channel with moving object
mergeFilter.OverlayImage = tmpImage3;
Bitmap tmpImage4 = mergeFilter.Apply( redChannel );
redChannel.Dispose( );
tmpImage3.Dispose( );
// replace red channel in the original image
replaceChannel.ChannelImage = tmpImage4;
Bitmap tmpImage5 = replaceChannel.Apply( image );
tmpImage4.Dispose( );
image.Dispose( );
image = tmpImage5;
}
// Calculate white pixels
private int CalculateWhitePixels( Bitmap image )
{
int count = 0;
// lock difference image
BitmapData data = image.LockBits( new Rectangle( 0, 0, width, height ),
ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed );
int offset = data.Stride - width;
unsafe
{
byte * ptr = (byte *) data.Scan0.ToPointer( );
for ( int y = 0; y < height; y++ )
{
for ( int x = 0; x < width; x++, ptr++ )
{
count += ( (*ptr) >> 7 );
}
ptr += offset;
}
}
// unlock image
image.UnlockBits( data );
return count;
}
}
}

Android buffer data and openCV processing function

/* Now allocate the buffer */
int dataBufferSize=(int)(optimalSize.height*optimalSize.width*(ImageFormat.getBitsPerPixel(parameters.getPreviewFormat())/8.0));
mBuffer= new byte[dataBufferSize];
/* The buffer where the current frame will be copied */
mFrame = new byte[dataBufferSize];
mCamera.addCallbackBuffer(mBuffer);
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback()
{
private long timestamp=0;
public synchronized void onPreviewFrame(byte[] data, Camera camera)
{
System.arraycopy(data, 0, mFrame, 0, data.length);
Log.i("Completed copying date","Ready for processing");
try{
camera.addCallbackBuffer(mBuffer);
}catch (Exception e)
{
Log.e("Camera", "addCallbackBuffer error");
return;
}
return;
}
});
void EyeBlink::blink(IplImage* frame)
{
CvSeq* comp = 0;
CvRect window, eye;
int key, nc, found;
int text_delay, stage = STAGE_INIT;
int valueBlink =0;
int delay, i;
capture = cvCaptureFromCAM(0);
if (!capture)
//exit_nicely("Cannot initialize camera!");
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, FRAME_WIDTH);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT);
frame = cvQueryFrame(capture);
if (!frame)
exit_nicely("cannot query frame!");
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.4, 0.4, 0, 1, 8);
cvNamedWindow(wnd_name, 1);
/*for (delay = 20, i = 0; i < 6; i++, delay = 20)
while (delay)
{
frame = cvQueryFrame(capture);
if (!frame)
exit_nicely("cannot query frame!");
DRAW_TEXT(frame, msg[i], delay, 0);
cvShowImage(wnd_name, frame);
cvWaitKey(30);
}*/
storage = cvCreateMemStorage(0);
if (!storage)
exit_nicely("cannot allocate memory storage!");
kernel = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_CROSS, NULL);
gray = cvCreateImage(cvGetSize(frame), 8, 1);
prev = cvCreateImage(cvGetSize(frame), 8, 1);
diff = cvCreateImage(cvGetSize(frame), 8, 1);
tpl = cvCreateImage(cvSize(TPL_WIDTH, TPL_HEIGHT), 8, 1);
if (!kernel || !gray || !prev || !diff || !tpl)
exit_nicely("system error.");
gray->origin = frame->origin;
prev->origin = frame->origin;
diff->origin = frame->origin;
cvNamedWindow(wnd_debug, 1);
while (key != 'q')
{
int t=100;
frame = cvQueryFrame(capture);
if (!frame)
exit_nicely("cannot query frame!");
frame->origin = 0;
if (stage == STAGE_INIT)
window = cvRect(0, 0, frame->width, frame->height);
cvCvtColor(frame, gray, CV_BGR2GRAY);
nc = get_connected_components(gray, prev, window, &comp);
if (stage == STAGE_INIT && is_eye_pair(comp, nc, &eye))
{
int i;
for (i = 0; i < 5; i++)
{
frame = frame1[i];
if (!frame)
exit_nicely("cannot query frame");
cvShowImage(wnd_name, frame);
if (diff)
cvShowImage(wnd_debug, diff);
cvWaitKey(30);
}
cvSetImageROI(gray, eye);
cvCopy(gray, tpl, NULL);
cvResetImageROI(gray);
stage = STAGE_TRACKING;
text_delay = 10;
}
if (stage == STAGE_TRACKING)
{
found = locate_eye(gray, tpl, &window, &eye);
if (!found || key == 'r')
stage = STAGE_INIT;
if (is_blink(comp, nc, window, eye))
text_delay = 10;
DRAW_RECTS(frame, diff, window, eye);
DRAW_TEXT(frame, "blink!", text_delay, 1);
}
cvShowImage(wnd_name, frame);
cvShowImage(wnd_debug, diff);
prev = (IplImage*)cvClone(gray);
key = cvWaitKey(15);
t--;
}
exit_nicely(NULL);
}
I am working on eye blink detection but having some challenges. First I captured the frames and buffered them by using setPreviewCallbackwithBuffer method in android but my question is how can I make use of the frames which were stored in bytes. Which means eliminating the cvCameraFromCam and cvQueryFrame functions from the code above.

Resources