OpenCV 2.1: Runtime error - c

I have a program which uses OpenCV. I have a webcam and it captures color frames and I want to convert the color frames to gray-scale frames. So, I used the cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY); to convert the color frames to BW frames.
Upon using this color->Grayscale conversion function, I get a runtime error as:
OpenCV Error: Null pointer (NULL array pointer is passed) in unknown function, file ..\..\..\..\ocv\opencv\src\cxcore\cxarray.cpp, line 2376
Anyone experienced this problem before? Any solutions how to fix this?
Thanks
My Program
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/time.h>
#include"cv.h"
#include"highgui.h"
#include"cxtypes.h"
#define ERROR -1
#define NO_ERROR 1
int main()
{
int EXIT_STATUS = NO_ERROR;
int camera_index = 0;
CvCapture *capture = 0;
IplImage *color_frame = NULL;
IplImage *gray_frame = NULL;
int exit_key_press = 0;
capture = cvCaptureFromCAM(camera_index);
cvNamedWindow("SURF", CV_WINDOW_AUTOSIZE);
while(exit_key_press != 's')
{
/* Capture a frame */
color_frame = cvQueryFrame(capture);
if(color_frame == NULL)
{
break;
}
else
{
// When this line is enabled the runtime error occurs.
//cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY);
cvShowImage("SURF", color_frame );
}
exit_key_press = cvWaitKey(1);
}
cvDestroyWindow("Output");
cvReleaseCapture(&capture);
printf("\n\n~*~The END~*~");
exit(EXIT_STATUS);
}

I see a lot of people trying to do this simple task and having trouble with it.
So I took the liberty of changing your source code into a program that would display on the screen the grayscale converted video from the webcam.
Please use this code for reference.
I compiled on my Macbook Pro with:
g++ -I/usr/include/opencv -c gray.cpp -o gray.o -m32 -arch i386
g++ gray.o -o gray -L/usr/lib -lcxcore -lcv -lhighgui -lcvaux -lml -ldl -m32 -arch i386
File: gray.cpp
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/time.h>
#include"cv.h"
#include"highgui.h"
#include"cxtypes.h"
#define ERROR -1
#define NO_ERROR 1
int main()
{
int camera_index = 0;
IplImage *color_frame = NULL;
int exit_key_press = 0;
CvCapture *capture = NULL;
capture = cvCaptureFromCAM(camera_index);
if (!capture)
{
printf("!!! ERROR: cvCaptureFromCAM\n");
return -1;
}
cvNamedWindow("Grayscale video", CV_WINDOW_AUTOSIZE);
while (exit_key_press != 'q')
{
/* Capture a frame */
color_frame = cvQueryFrame(capture);
if (color_frame == NULL)
{
printf("!!! ERROR: cvQueryFrame\n");
break;
}
else
{
IplImage* gray_frame = cvCreateImage(cvSize(color_frame->width, color_frame->height), color_frame->depth, 1);
if (gray_frame == NULL)
{
printf("!!! ERROR: cvCreateImage\n");
continue;
}
cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY);
cvShowImage("Grayscale video", gray_frame);
cvReleaseImage(&gray_frame);
}
exit_key_press = cvWaitKey(1);
}
cvDestroyWindow("Grayscale video");
cvReleaseCapture(&capture);
return 0;
}

Don't you have to allocate your IplImage? It is not specified by the conversion function but I believe you have to allocate a dst the same size/type as the source.

Related

How can I make Motif Push Button widget to appear as permanently pushed?

I have written a simple tool to select an audio channel in FreeBSD.
This is the code:
xaudio.c
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/MainW.h>
#include <Xm/RowColumn.h>
#include <stdio.h>
#include <stdlib.h>
#include "devices.h"
struct button_data {
int device_num;
Widget button;
};
/* GLOBAL VARIABLES */
int num_devices;
struct device *devices;
struct button_data *buttons;
void button_callback(Widget widget, XtPointer client_data, XtPointer call_data);
void create_device_buttons(Widget parent, struct device *devices, int num_devices);
void button_callback(Widget widget, XtPointer client_data, XtPointer call_data) {
int i;
struct button_data *data = (struct button_data *)client_data;
int device_num = data->device_num;
// unclick all other buttons
for (i = 0; i < num_devices; i++) {
if (buttons[i].button != widget) {
XtVaSetValues(buttons[i].button, XmNset, False, NULL);
}
}
// click this button
XtVaSetValues(widget, XmNset, True, NULL);
// set audio device
set_audio_device(device_num);
}
void create_device_buttons(Widget parent, struct device *devices, int num_devices) {
int i;
XmString label;
struct button_data *data;
Arg args[5];
int n;
buttons = malloc(num_devices * sizeof(struct button_data));
if (buttons == NULL) {
perror("Failed to allocate memory");
exit(EXIT_FAILURE);
}
for (i = 0; i < num_devices; i++) {
// create button
n = 0;
label = XmStringCreateLocalized(devices[i].description);
XtSetArg(args[n], XmNlabelString, label); n++;
buttons[i].button = XmCreatePushButton(parent, "device_button", args, n);
XmStringFree(label);
XtManageChild(buttons[i].button);
// set button data
buttons[i].device_num = devices[i].number;
// set button callback
XtAddCallback(buttons[i].button, XmNactivateCallback, button_callback, &buttons[i]);
}
}
int main(int argc, char *argv[]) {
XtAppContext app;
Widget top_level, main_window, button_rowcolumn;
int default_device;
int n=0;
Arg args[10];
top_level = XtVaOpenApplication(&app, "XAudio", NULL, 0, &argc, argv, NULL, sessionShellWidgetClass, NULL);
main_window = XmCreateMainWindow(top_level, "main_window", NULL, 0);
XtManageChild(main_window);
n=0;
XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
button_rowcolumn = XmCreateRowColumn(main_window, "button_rowcolumn", args, n);
XtManageChild(button_rowcolumn);
/* GET LIST OF DEVICES AND DEFAULT DEVICE */
default_device = get_default_device(&devices, &num_devices);
int i=0;
for(i=0; i<num_devices; i++) {
printf("%d %s\n", devices[i].number, devices[i].description);
}
create_device_buttons(button_rowcolumn, devices, num_devices);
XtRealizeWidget(top_level);
/* CLICK DEFAULT BUTTON */
if (default_device >= 0) {
XtVaSetValues(buttons[default_device].button, XmNset, True, NULL);
}
XtAppMainLoop(app);
free(devices);
free(buttons);
return 0;
}
devices.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct device {
int number;
char description[256];
};
void set_audio_device(int device_num) {
char command[256];
sprintf(command, "sysctl hw.snd.default_unit=%d", device_num);
system(command);
}
int get_default_device(struct device **devices, int *num_devices) {
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
int num_dev = 0;
int default_device = -1;
fp = popen("cat /dev/sndstat", "r");
if (fp == NULL) {
perror("Failed to run command");
exit(EXIT_FAILURE);
}
while ((read = getline(&line, &len, fp)) != -1) {
if (strstr(line, "pcm") == line) {
// line starts with "pcm", so it is a device line
// increase number of devices and reallocate memory
num_dev++;
*devices = realloc(*devices, num_dev * sizeof(struct device));
if (*devices == NULL) {
perror("Failed to allocate memory");
exit(EXIT_FAILURE);
}
// get device number
sscanf(line, "pcm%d:", &(*devices)[num_dev - 1].number);
// get description
char *start = strchr(line, '<');
char *end = strchr(line, '>');
if (start != NULL && end != NULL) {
int length = end - start - 1;
strncpy((*devices)[num_dev - 1].description, start + 1, length);
(*devices)[num_dev - 1].description[length] = '\0';
}
// check if this is the default device
if (strstr(line, "default") != NULL) {
default_device = num_dev - 1;
}
}
}
*num_devices = num_dev;
pclose(fp);
return default_device;
}
devices.h:
#ifndef DEVICES_H
#define DEVICES_H
#include <stdio.h>
#include <stdlib.h>
struct device {
int number;
char description[256];
};
void set_audio_device(int device_num);
int get_default_device(struct device **devices, int *num_devices);
#endif
And the corresponding makefile (for FreeBSD):
CC = cc
CFLAGS = -Wall -Wextra -I/usr/local/include
LDFLAGS = -Wall -Wextra -L/usr/local/lib -lXm -lXt -lX11
all: xaudio
xaudio: xaudio.o devices.o
$(CC) $(LDFLAGS) -o $# xaudio.o devices.o
xaudio.o: xaudio.c devices.h
$(CC) $(CFLAGS) -c -o $# $<
devices.o: devices.c devices.h
$(CC) $(CFLAGS) -c -o $# $<
clean:
rm -f *.o xaudio
The program compiles and works (it switches the audio channel as expected). However, my intended behaviour was that the channel selected appeared as a permanently pushed button, and that when a new channel was selected the pushed button changed accordingly. Sort kind of "selectable button set".
It is my understanding that such behaviour was achieved by the following widget parameter:
XtVaSetValues(buttons[default_device].button, XmNset, True, NULL);
However, as seen here, this is not happening and the buttons appear always unclicked except the normal dynamic click effect when pressed.
The desired behaviour you describe is what "radio buttons" are for. In Motif, I believe you need the XmCreateRadioBox function.
No, XmPushButton cant be configured to looked always pushed.
Try using XmToggleButton instead of XmPushButton. Set XmNindicatorOn to False to get rid of the diamond checkbox. Then XmNset,False will make it looked pressed.

getting virtual memory address(vma) of linker symbols

I'm playing around the bfd library (<bfd.h>), and I was able to implement my own version of objdump -h on binary files by printing out sections, their vmas, size, etc. Now, I'm having trouble implementing nm. I'm able to use the bfd library to obtain all the different symbols of a binary executable file, but how can I get each symbol's (main, etc) vma using asection/asymbol struct data? Here's the code I have that prints out every symbol name:
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <bfd.h>
int main(int argc, char *argv[])
{
bfd *ibfd = NULL;
if (!argv[1])
{
printf("Please supply a second argument\n");
return -1;
}
else
{
// initialize bfd so we can use it
bfd_init();
// open the supplied argument file
const char *str = argv[1];
ibfd = bfd_openr(str, "elf64-x86-64");
// if issue opening
if (!ibfd)
{
bfd_perror("open failure\n");
return -1;
}
// if file isnt elf binary file
if (!bfd_check_format(ibfd, bfd_object))
{
printf("not an object file\n");
return -1;
}
int spaceNeeded = bfd_get_symtab_upper_bound(ibfd);
if (spaceNeeded < 0)
{
return -1;
}
else if (spaceNeeded == 0)
{
return 1;
}
asymbol **symTable = malloc(spaceNeeded);
long numSyms = bfd_canonicalize_symtab(ibfd, symTable);
if (numSyms < 0)
return -1;
for (int i = 0, count = 0; i < numSyms; i++)
{
printf("%s\n", symTable[i]->name);
}
bfd_close(ibfd);
}
// success code
return 1;
}
nm uses the function bfd_symbol_info to fetch the virtual memory addresses of the symbols. You can read the source code for that function to get an idea as to the implementation.
void
bfd_symbol_info (symbol, ret)
asymbol *symbol;
symbol_info *ret;
{
ret->type = bfd_decode_symclass (symbol);
if (bfd_is_undefined_symclass (ret->type))
ret->value = 0;
else
ret->value = symbol->value + symbol->section->vma;
ret->name = symbol->name;
}

libxml2 get xsd validation errors

I'm using xmlTextReader to process large xml files. Now i need to validate the instance against an xsd schema. The api from libxml2 is a little bit confusing, how this is done.
With my approach, im getting the validation errors in the schemaParseErrorHandler function, but without any line numbers or column numbers.
How can i get these informations?
#include <stdio.h>
#include <libxml/xmlreader.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
static void schemaParseErrorHandler(void *arg, xmlErrorPtr error)
{
fprintf( stderr, "Error at line %d, column %d\n%s",
error->line, error->int2, error->message);
*((bool*)arg) = true;
}
int main( int argc, char **argv )
{
xmlInitParser();
xmlSchemaPtr schema = NULL;
xmlSchemaParserCtxtPtr schema_parser_ctxt = NULL;
int has_schema_errors = 0;
int ret = -1;
xmlSchemaValidCtxtPtr valid_ctxt = NULL;
if ((schema_parser_ctxt = xmlSchemaNewParserCtxt("example.xsd")))
{
schema = xmlSchemaParse(schema_parser_ctxt);
xmlSchemaFreeParserCtxt(schema_parser_ctxt);
if (schema)
{
valid_ctxt = xmlSchemaNewValidCtxt(schema);
}
}
xmlTextReaderPtr reader = NULL;
reader = xmlReaderForFile(filename, RPCXmlStream::STD_ENCODING, 0);
if (reader != NULL)
{
if (valid_ctxt)
{
xmlTextReaderSchemaValidateCtxt(reader, valid_ctxt, 0);
xmlSchemaSetValidStructuredErrors(valid_ctxt, schemaParseErrorHandler, &has_schema_errors);
}
ret = xmlTextReaderRead(reader);
while (ret == 1 && !has_schema_errors)
{
//... procesing informations
ret = xmlTextReaderRead(reader);
}
}
if (ret != 0)
{
xmlErrorPtr err = xmlGetLastError();
TRACE("%s: failed to parse in line %d, col %d. Error %d: %s\n",
err->file,
err->line,
err->int2,
err->code,
err->message);
}
xmlFreeTextReader(reader);
xmlCleanupParser();
return 0;
}
Another try was to use the function
xmlTextReaderSchemaValidate(reader, "example.xsd");
instead of creating an xmlSchemaNewValidCtxt, but than the programm is crashing on the first call to xmlTextReaderRead.
So how is validation done right, so that the error informations includes line and column numbers?
So, your questions got me thinking and when I looked in the libxml2 documentation,
Structure xmlError
struct _xmlError {
int domain : What part of the library raised this er
int code : The error code, e.g. an xmlParserError
char * message : human-readable informative error messag
xmlErrorLevel level : how consequent is the error
char * file : the filename
int line : the line number if available
char * str1 : extra string information
char * str2 : extra string information
char * str3 : extra string information
int int1 : extra number information
int int2 : error column # or 0 if N/A (todo: renam
void * ctxt : the parser context if available
void * node : the node in the tree
}
where we can clearly see that the xmlErrorPtr which is returned by the function xmlGetLastError() clearly contains information about the filename and the line number and the column number.
char * file : the filename
int line : the line number if available
...
int int2 : error column
So to test if this was possible or not, here is the code that I used (basically your code with minor changes to make it run on my system):
#include <stdio.h>
#include <stdbool.h>
#include <libxml/xmlreader.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
static void schemaParseErrorHandler(void *arg, xmlErrorPtr error)
{
fprintf(stderr, "Error at line %d, column %d\n%s", error->line, error->int2, error->message);
*((bool*)arg) = true;
}
int main( int argc, char **argv )
{
xmlInitParser();
xmlSchemaPtr schema = NULL;
xmlSchemaParserCtxtPtr schema_parser_ctxt = NULL;
int has_schema_errors = 0;
int ret = -1;
xmlSchemaValidCtxtPtr valid_ctxt = NULL;
if ((schema_parser_ctxt = xmlSchemaNewParserCtxt("/home/junglefox/shiporder.xsd")))
{
schema = xmlSchemaParse(schema_parser_ctxt);
xmlSchemaFreeParserCtxt(schema_parser_ctxt);
if (schema)
{
valid_ctxt = xmlSchemaNewValidCtxt(schema);
}
}
xmlTextReaderPtr reader = NULL;
const char* filename = "/home/junglefox/shiporder.xml";
reader = xmlReaderForFile(filename, /*RPCXmlStream::STD_ENCODING,*/ NULL, 0);
if (reader != NULL)
{
if (valid_ctxt)
{
xmlTextReaderSchemaValidateCtxt(reader, valid_ctxt, 0);
xmlSchemaSetValidStructuredErrors(valid_ctxt, schemaParseErrorHandler, &has_schema_errors);
}
ret = xmlTextReaderRead(reader);
while (ret == 1 && !has_schema_errors)
{
//... procesing informations
ret = xmlTextReaderRead(reader);
}
}
if (ret != 0)
{
xmlErrorPtr err = xmlGetLastError();
fprintf(stdout, "%s: failed to parse in line %d, col %d. Error %d: %s\n",
err->file,
err->line,
err->int2,
err->code,
err->message);
}
xmlFreeTextReader(reader);
xmlCleanupParser();
return 0;
}
where, the shiporder.xml and shiporder.xsd used in that program were copied from the url and saved locally.
I compiled and ran the code like this:
junglefox#ubuntu:~$ gcc -o test_xsd main.c -I/usr/include/libxml2/ -lxml2 -L/usr/lib/x86_64-linux-gnu/
junglefox#ubuntu:~$ ./test_xsd
junglefox#ubuntu:~$
The output this time was nothing. As it should be as there were no errors.
If however now I make an intentional error in the shiporder.xml file, as shown below:
Here is the partial-snippet from the buggy shiporder.xml:
<?xml version="1.0" encoding="UTF-8"?>
...
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
price>9.90</price>
</item>
</shiporder>
Notice the missing < before price!
Now I run the program again,
junglefox#ubuntu:~$ ./test_xsd
Error at line 22, column 0
Element 'item': Character content other than whitespace is not allowed because the content type is 'element-only'.
which answers your question(s):
With my approach, im getting the validation errors in the schemaParseErrorHandler function, but without any line numbers or column numbers. How can i get these informations?
and,
So how is validation done right, so that the error informations includes line and column numbers?
as the output clearly shows the line number 22 and column 0, where there was an unexpected empty space due to the missing <.

I am getting fatal error when i run my code OpenCV code using OpenMP(C/C++)

I want to parallelize the execution of this program, but when i run this,i got a fatal error. OpenCV parallelization with OpenMP using C.Your Help will be appreciated. I am newbee to OpenMP and OpenCV.
#include <cv.h>
#include <cvaux.h>
#include <iostream>
#include <cxcore.h>
#include <highgui.h>
#include <omp.h>
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
int no_of_frames = 0,i,j;
int fps = 0;
int mid_frame = 0;
CvCapture* capture = cvCaptureFromFile("/home/nagaraj/ImageVideo/tunnel.avi");
CvCapture* captureNew = cvCaptureFromFile("/home/nagaraj/ImageVideo/tunnel.avi");
if (capture == NULL)
{
printf("Error: Can't open video.\n");
return -1;
}
if (capture == NULL)
{
printf("Error: Can't open video.\n");
return -1;
}
fps = (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FPS);
no_of_frames = (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT);
mid_frame = no_of_frames/2;
omp_set_num_threads(2);
#pragma omp parallel sections
{
#pragma omp section
{
//cvSetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES,0);
IplImage* img = cvQueryFrame(capture);
cvNamedWindow("Window1",CV_WINDOW_AUTOSIZE);
cvShowImage("Window1",img);
cvWaitKey(10000);
cvReleaseImage(&img);
cvDestroyWindow("Window1");
cvReleaseCapture(&capture);
}
#pragma omp section
{
cvSetCaptureProperty(captureNew,CV_CAP_PROP_POS_FRAMES,(double)mid_frame-1);
IplImage* img = cvQueryFrame(captureNew);
cvNamedWindow("Window2",CV_WINDOW_AUTOSIZE);
cvShowImage("Window2",img);
cvWaitKey(10000);
cvReleaseImage(&img);
cvDestroyWindow("Window2");
cvReleaseCapture(&captureNew);
}
}
}
There are several potential problems in the code:
The most probable cause of is cvReleaseImage() being called to free a resource that wasn't created by you. In this case, the IplImage was created internally by cvQueryFrame(). Doing this can crash your application.
Print the values of fps, no_of_frames and mid_frame to the screen. The functions that are called to retrieve these values can fail and return 0, which would then cause a problem in your application since you pass some of these data to cvSetCaptureProperty().
Sometimes cvQueryFrame() can return NULL indicating that there was some problem while retrieving a frame. Passing a NULL frame to cvShowImage() can also crash your application:
IplImage* img = cvQueryFrame(capture);
if (img == NULL) {
// handle error
}

HarfBuzz - hb_shape() leads to access violation

Based on this example, I try to implement font rendering in my SDL application. When calling hb_shape(), the application is halted because of an access-violation.
DLL-download-link (win32): here {harfbuzz-0.9.26-win32.zip}
ErrorMsg (VC2012): Unhandled exception at 0x6160B7F0 (libharfbuzz-0.dll)in ConsoleApplication2.exe: 0xC0000005: Access violation while reading at position 0x00000068
EDIT: I changed the example to a console application, for simplicity.
Edit2: Now linking statically, .lib-file created with VC++'s LIB.exe.
#include <Windows.h>
#include <iostream>
#include <hb.h>
#include <hb-ft.h>
#pragma comment(lib,"lib/x86/freetype253ST.lib") // freetype single-thread
#pragma comment (lib,"libharfbuzz-0.lib") // linked to libharfbuzz.dll, created by LIB.exe
int main()
{
hb_font_t* font = NULL;
hb_buffer_t* buffer = NULL;
FT_Library flib;
FT_Face face;
bool found = false;
const char text[] = {"Write something...."};
if (FT_Init_FreeType(&flib) == 0)
{
if (FT_New_Face(flib,"arial.ttf",0,&face) == 0)
{
for (int i = 0; i < face->num_charmaps; i++)
{ // search for UNICODE 2.0 charmap
if ((face->charmaps[i]->encoding_id == 3 && face->charmaps[i]->platform_id == 0) ||
(face->charmaps[i]->encoding_id == 1 && face->charmaps[i]->platform_id == 3) )
{
FT_Set_Charmap(face,face->charmaps[i]);
found = true;
break;
}
}
if (found && FT_Set_Char_Size(face,0,50*64,72,72) == 0)
{
font = hb_ft_font_create(face,NULL);
buffer = hb_buffer_create();
if (hb_buffer_allocation_successful(buffer))
{
hb_buffer_set_script(buffer,HB_SCRIPT_LATIN);
hb_buffer_set_language(buffer, hb_language_from_string("en",strlen("en"))); // strlen("en") is awful but good enough here
hb_buffer_set_direction(buffer,HB_DIRECTION_LTR);
hb_buffer_add_utf8(buffer,text,strlen(text),0,strlen(text));
hb_shape(font,buffer,NULL,0); // Access violation
std::cout << "There\n";
hb_buffer_destroy(buffer);
}
hb_font_destroy(font);
}
FT_Done_Face(face);
}
FT_Done_FreeType(flib);
}
Sleep(3000);
return 0;
}

Resources