Capture video from camera in Mac OS X - c

How I can filter video stream from camera in MacOS X. I write quicktime sequence grabber channel component, but it`s work only if app used SG API. If app used QTKit Capture the component is not worked.
Somebody know how I can implement it?

You could use OpenCV for video processing, it's a cross platform image/video processing library: http://opencv.willowgarage.com
Your code would look something like this:
CvCapture* capture = NULL;
if ((capture = cvCaptureFromCAM(-1)) == NULL)
{
std::cerr << "!!! ERROR: vCaptureFromCAM No camera found\n";
return -1;
}
cvNamedWindow("webcam", CV_WINDOW_AUTOSIZE);
cvMoveWindow("webcam", 50, 50);
cvQueryFrame(capture);
IplImage* src = NULL;
for (;;)
{
if ((src = cvQueryFrame(capture)) == NULL)
{
std::cerr << "!!! ERROR: vQueryFrame\n";
break;
}
// perform processing on src->imageData
cvShowImage("webcam", &src);
char key_pressed = cvWaitKey(2);
if (key_pressed == 27)
break;
}
cvReleaseCapture(&camera);
I had success using OpenCV on Mac OS X using cvCaptureFromCAM(0) instead of passing it -1. On linux, -1 seems to do Ok.

It looks like there should be cvReleaseCapture(&capture); at the end.

Related

Disable pn53x_check_communication: Input / Output Error message

I'm using libnfc 1.7.1 compiled with c to read from a PN532 reader on a Raspberry Pi. The goal is to make a node for Node-RED that injects the UID of the scanned card or pass errors along about library or reader. I modified the example to give me the UID of a card as the only normal output. I can't have anything printed other than an error when the library can't be loaded, an error when the reader can't be connected, or the UID of the card. I changed the log level to 0 in /etc/nfc/libnfc.conf but my program is still printing "pn53x_check_communication: Input / Output Error" (unwanted) as well as "ERROR: Unable to open NFC device." (wanted) I can't find any way to disable the I/O error message. I looked in the library and found this that returns NFC_EIO which is the I/O error I'm getting, but can't find anywhere that it actually prints that. Short of modifying the library I can't find any way to disable this print. If there is nothing that can be done I can program my node to ignore this output but I would rather eliminate it. My code is below:
#include <stdlib.h>
#include <nfc/nfc.h>
static void
print_long(const uint8_t *pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos = 0; szPos < szBytes; szPos++) {
printf("%03lu", pbtData[szPos]);
}
printf("\n");
}
int
main(int argc, const char *argv[])
{
nfc_device *pnd;
nfc_target nt;
// Allocate only a pointer to nfc_context
nfc_context *context;
// Initialize libnfc and set the nfc_context
nfc_init(&context);
if (context == NULL) {
printf("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
// Open, using the first available NFC device which can be in order of selection:
// - default device specified using environment variable or
// - first specified device in libnfc.conf (/etc/nfc) or
// - first specified device in device-configuration directory (/etc/nfc/devices.d) or
// - first auto-detected (if feature is not disabled in libnfc.conf) device
pnd = nfc_open(context, NULL);
//Send error
if (pnd == NULL) {
printf("ERROR: %s\n", "Unable to open NFC device.");
exit(EXIT_FAILURE);
}
// Set opened NFC device to initiator mode
if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init");
exit(EXIT_FAILURE);
}
while(true){
// Poll for a ISO14443A (MIFARE) tag
const nfc_modulation nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
//Print decimal version of UID and wait until it's removed to scan again
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) > 0) {
print_long(nt.nti.nai.abtUid, nt.nti.nai.szUidLen);
while (0 == nfc_initiator_target_is_present(pnd, NULL)) {}
}
}
}

IIO device buffer always null

I am using an IMU sensor called LSM6DSL with the iio drivers. They work fine if I display the raw values with the command:
cat /sys/bus/iio/devices/iio:device0/in_accel_x_raw
Then I decided to use the libiio so I can read all these values from a C program :
struct iio_context *context = iio_create_local_context();
struct iio_device *device = iio_context_get_device(context, 1);
struct iio_channel *chan = iio_device_get_channel(device, 0);
iio_channel_enable(chan);
if (iio_channel_is_scan_element(chan) == true)
printf("OK\n");
struct iio_channel *chan2 = iio_device_get_channel(device, 1);
iio_channel_enable(chan2);
struct iio_buffer *buff = iio_device_create_buffer(device, 1, true);
if (buff == NULL)
{
printf("Error: %s\n", strerror(errno));
return (1);
}
And this is the result :
OK
Error: Device or resource busy
Am I missing something? Let me know if you need more informations.
I guess I found the answer, and I didn't pay attention to the effects of the ncurses library (sorry for not mentioning that I was using it).
I moved these functions before the initialization of ncurses and now the buffer is created successful.

how to Find the Mount Path of Pendrive in better way?

I have a requirement like . My Embedded system consist of program which on start up looks for a pendrive and specific directory in pendrive. if the directories are found its considered as bootable device.
Consider Below code :
uint8 Check_BB_rootfs_Availability()
{
uint8 b_flag = 0x00;
dw_PkgAvailFlag |= BB_PKG_AVAIL_MASK;
if(!(system("ls /media1/sda/UPGRADE_FILES/BB/")))
{
path_argv[0] = "/media1/sda/UPGRADE_FILES/BB/rootfs.ubifs";
}
else if(!(system("ls /media1/sda1/UPGRADE_FILES/BB/")))
{
path_argv[0] = "/media1/sda/UPGRADE_FILES/BB/rootfs.ubifs";
}
else if(!(system("ls /media2/sda/UPGRADE_FILES/BB/")))
{
path_argv[0] = "/media2/sda/UPGRADE_FILES/BB/rootfs.ubifs";
}
else if(!(system("ls /media2/sda1/UPGRADE_FILES/BB/")))
{
path_argv[0] = "/media2/sda1/UPGRADE_FILES/BB/rootfs.ubifs";
}
else if(!(system("ls /media/sda/UPGRADE_FILES/BB/")))
{
path_argv[0] = "/media/sda/UPGRADE_FILES/BB/rootfs.ubifs";
}
else if(!(system("ls /media/sda1/UPGRADE_FILES/BB/")))
{
path_argv[0] = "/media/sda1/UPGRADE_FILES/BB/rootfs.ubifs";
}
else
{
/* Normal Boot */
dw_PkgAvailFlag &= ~(BB_PKG_AVAIL_MASK);
b_flag = 0x01;
}
return b_flag;
}
If rootfs is available . I call a script which does the upgrading .
Can this be done in some better way instead of using if..else condition and the systemcall.
Also I am facing another issue is when i am using system call i.e i cannot pass the char * path_argv[0] as an argument to system call. again i have to do is this
system("/media/sda1/UPGRADE_FILES/BB/UPGRADEBB_File.sh '/media/sda1/UPGRADE_FILES/BB/rootfs.ubifs'");
can some way i can pass the pointer without using the execv call as i dont want to create new process.
You might like to have a look at the stat() system call. It allows you to test for the existance of a certain file or directory.
You can use sprintf() to "print" into a "string".
char cmd[1024] = ""; /* Make sure this buffer is large enough. */
sprintf(cmd, "/media/sda1/UPGRADE_FILES/BB/UPGRADEBB_File.sh '%s'", path_argv[0]);
int result = system(cmd);

read/write avi video on MAC using openCV

I am trying to read avi video and write it again as it is without any change using openCV 2.4.0 on MAC 10.6.8
My videos is grayscale with frame_rate = 25 and Codec = 827737670 which is FFV1 (I guess)
The problem is ....
when I read and write the video as it is .... I see many changes in size and in color ...
After 3 or 4 times of writing I can see the video start to be (Pink) color !!!
I am not sure what is the problem !!!
this is my code for the people who interest
Appreciate your help in advance :D
Seereen
Note : I have on my computer FFMPEG V 0.11 (I do not know if this important)
{
int main (int argc, char * const argv[]) {
char name[50];
if (argc==1)
{
printf("\nEnter the name of the video:");
scanf("%s",name);
} else if (argc == 2)
strcpy(name, argv[1]);
else
{
printf("To run this program you should enter the name of the program at least, or you can enter the name of the program then the file name");
return 0;
}
cvNamedWindow( "Read the video", CV_WINDOW_AUTOSIZE );
// GET video
CvCapture* capture = cvCreateFileCapture( name );
if (!capture )
{
printf( "Unable to read input video." );
return 0;
}
double fps = cvGetCaptureProperty( capture,CV_CAP_PROP_FPS);
printf( "fps %f ",fps );
int codec = cvGetCaptureProperty( capture,CV_CAP_PROP_FOURCC);
printf( "codec %d ",codec );
// Read frame
IplImage* frame = cvQueryFrame( capture );
// INIT the video writer
CvVideoWriter *writer = cvCreateVideoWriter( "x7.avi", codec, fps, cvGetSize(frame),1);
while(1)
{
cvWriteFrame( writer, frame );
cvShowImage( "Read the video", frame );
// READ next frame
frame = cvQueryFrame( capture );
if( !frame )
break;
char c = cvWaitKey(33);
if( c == 27 )
break;
}
// CLEAN everything
cvReleaseImage( &frame );
cvReleaseCapture( &capture );
cvReleaseVideoWriter( &writer );
cvDestroyWindow( "Read the video" );
return 0;}
}
Check this list of fourcc codes, and search for the uncompressed ones, like HFYU.
You also might find this article interesting: Truly lossless video recording with OpenCV.
EDIT:
I have a Mac OS X 10.7.5 at my disposal and since you gave us the video for testing I decided to share my findings.
I wrote the following source code for testing purposes: it loads your video file and writes it to a new file out.avi while preserving the codec information:
#include <cv.h>
#include <highgui.h>
#include <iostream>
int main(int argc, char* argv[])
{
// Load input video
cv::VideoCapture input_cap(argv[1]);
if (!input_cap.isOpened())
{
std::cout << "!!! Input video could not be opened" << std::endl;
return -1;
}
// Setup output video
cv::VideoWriter output_cap("out.avi",
input_cap.get(CV_CAP_PROP_FOURCC),
input_cap.get(CV_CAP_PROP_FPS),
cv::Size(input_cap.get(CV_CAP_PROP_FRAME_WIDTH), input_cap.get(CV_CAP_PROP_FRAME_HEIGHT)));
if (!output_cap.isOpened())
{
std::cout << "!!! Output video could not be opened" << std::endl;
return -1;
}
// Loop to read from input and write to output
cv::Mat frame;
while (true)
{
if (!input_cap.read(frame))
break;
output_cap.write(frame);
}
input_cap.release();
output_cap.release();
return 0;
}
The output video presented the same characteristics of the input:
Codec: FFMpeg Video 1 (FFV1)
Resolution: 720x480
Frame rate: 25
Decoded format: Planar 4:2:0 YUV
and it looked fine when playing.
I'm using OpenCV 2.4.3.
I figure out the problem ,,,,,
The original videos written in YUV240 pixel format (and it is gray)
the openCV read the video on BGR by default , so each time when I read it the openCV convert the pixel values to BGR
after few time of reading and writing , the error start to be bigger (because the conversion operation)
that why the pixels values change .....and I see the video pink !
The Solution is , read and write this kind of videos by FFMPEG project which provide YUV240 and many other format
there is a code can do this operation in the tutorial of FFMPEG
I hope this can help the others who face similar problem

How do I use Minizip (on Zlib)?

I'm trying to archive files for a cross-platform application, and it looks like Minizip (built on zlib) is about as portable as archivers come.
When I try to run the following dummy code, however, I get a system error [my executable] has stopped working. Windows can check online for a solution to the problem.
Can anyone help me see how to use this library? — (there's no doc or tutorial anywhere that I can find)
zip_fileinfo zfi;
int main()
{
zipFile zf = zipOpen("myarch.zip",APPEND_STATUS_ADDINZIP);
int ret = zipOpenNewFileInZip(zf,
"myfile.txt",
&zfi,
NULL, 0,
NULL, 0,
"my comment for this interior file",
Z_DEFLATED,
Z_NO_COMPRESSION
);
zipCloseFileInZip(zf);
zipClose(zf, "my comment for exterior file");
return 0;
}
Specs: Msys + MinGW, Windows 7, using zlibwapi.dll from zlib125dll.zip/dll32
Since I found this question via Google and it didn't contain any complete, working code, I am providing some here for future visitors.
int CreateZipFile (std::vector<wstring> paths)
{
zipFile zf = zipOpen(std::string(destinationPath.begin(), destinationPath.end()).c_str(), APPEND_STATUS_CREATE);
if (zf == NULL)
return 1;
bool _return = true;
for (size_t i = 0; i < paths.size(); i++)
{
std::fstream file(paths[i].c_str(), std::ios::binary | std::ios::in);
if (file.is_open())
{
file.seekg(0, std::ios::end);
long size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<char> buffer(size);
if (size == 0 || file.read(&buffer[0], size))
{
zip_fileinfo zfi = { 0 };
std::wstring fileName = paths[i].substr(paths[i].rfind('\\')+1);
if (S_OK == zipOpenNewFileInZip(zf, std::string(fileName.begin(), fileName.end()).c_str(), &zfi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION))
{
if (zipWriteInFileInZip(zf, size == 0 ? "" : &buffer[0], size))
_return = false;
if (zipCloseFileInZip(zf))
_return = false;
file.close();
continue;
}
}
file.close();
}
_return = false;
}
if (zipClose(zf, NULL))
return 3;
if (!_return)
return 4;
return S_OK;
}
The minizip library does come with examples; minizip.c for zipping and miniunz.c for unzipping. Both are command line utilities that show how to use the library. They are a mess though.
You also need to fill the zfi zip_fileinfo. At the very least you should initialize the structure to zero. zfi contains information about the file you want to store using zipOpenNewFileInZip. The structure should contain the date and attributes of "myfile.txt".
I recommend using PKWARE Desktop to diagnosis zip issues. It shows the structure/properties of the files in the ZIP and the ZIP file itself. When I opened the myarch.zip it told me there were errors. I drilled down into the file properties and found that the attributes were off.
The minizip lib is well documented. Just open the zip.h for details.
I can tell you here, you may have passed a wrong parameter for zipOpen. (APPEND_STATUS_ADDINZIP requires an existing zip file!)
Also, please check whether zipOpen returns a valid zipFile handle.

Resources