Colour conversion not working in opencv? - c

#include<highgui.h>
#include<cxcore.h>
#include<cv.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{
IplImage* img = cvLoadImage("hello.jpg", CV_WINDOW_FULLSCREEN );
int *img_data;
img_data = malloc(sizeof(*img_data)*img->height*img->width*img->nChannels);
if (!img)
{
printf("Image can NOT Load!!!\n");
return 1;
}
cvNamedWindow("myfirstwindow", CV_WINDOW_FREERATIO );
cvShowImage("myfirstwindow", img);
printf("Height: %d\nwidth: %d\nnchannels:%d\n",img->height,img->width,img->nChannels);
cvCvtColor(img,img_data,CV_RGB2XYZ);
cvWaitKey(0);
cvReleaseImage(&img);
return 0;
}
In this program I am trying to convert RGB color model to XYZ color model using function cvCvtColor. And i am getting error shown below:
OpenCV Error: Bad argument (Unknown array type) in cvarrToMat, file
/build/buildd/opencv-2.3.1/modules/core/src/matrix.cpp, line 646
terminate called after throwing an instance of 'cv::Exception'
what(): /build/buildd/opencv-2.3.1/modules/core/src/matrix.cpp:646:
error: (-5) Unknown array type in function cvarrToMat
Any help or suggestion will be greatly appreciated. Thank you.

do yourself (and us) a favour, and switch to the c++ api.
the old c-api is no longer developed, and only around for maintenance, don't write any new code in that !
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
using namespace cv;
int main()
{
namedWindow("myfirstwindow", CV_WINDOW_FREERATIO );
Mat img = imread("hello.jpg", CV_IMAGE_LOAD_COLOR);
imshow("myfirstwindow",img);
Mat hsv;
cvtColor(img,hsv,CV_RGB2HSV);
waitKey(0);
return 0;
}

You are passing enum value CV_WINDOW_FULLSCREEN which is meant for specifying the property of window when calling cvNamedWindow. For image loading, it should be some enum value like CV_LOAD_IMAGE_COLOR or CV_LOAD_IMAGE_GRAYSCALE.
But your code is not crashing here because fortunately, the integral value of CV_WINDOW_FULLSCREEN and CV_LOAD_IMAGE_COLOR is same, i.e. 1, so basically these enum values are equal.
The real cause of error in the code is you are passing raw int* to the function cvCvtColor. All opencv C functions expect IplImage* as arguments. The following line is causing the error.
cvCvtColor(img,img_data,CV_RGB2XYZ);
You might want to do something like this:
int main(int argc, char* argv[])
{
IplImage* img = cvLoadImage("hello.jpg", CV_LOAD_IMAGE_COLOR);
IplImage *img_data;
img_data = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
if (!img)
{
printf("Image can NOT Load!!!\n");
return 1;
}
cvNamedWindow("myfirstwindow", CV_WINDOW_FREERATIO );
cvShowImage("myfirstwindow", img);
printf("Height: %d\nwidth: %d\nnchannels:%d\n",img->height,img->width,img->nChannels);
cvCvtColor(img,img_data,CV_RGB2XYZ);
cvWaitKey(0);
cvReleaseImage(&img);
cvReleaseImage(&img_data);
return 0;
}

You need to pass CV_LOAD_IMAGE_COLOR to the function cvLoadImage(), which will load color image.

Related

erorr reading Rgb Images uisng imLIb2

I am trying to read a raw RGBA image using imLIb2 (https://docs.enlightenment.org/api/imlib2/html/ -> according to this page it seems like they accept RGBA data for images)
#include <Imlib2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
/* an image handle */
Imlib_Image image;
/* load the image */
Imlib_Load_Error error;
image = imlib_load_image_with_error_return("rgba.raw", &error);
printf("load error:%d", error);
if (image)
{
imlib_context_set_image(image);
imlib_image_set_format("png");
/* save the image */
imlib_save_image("working.png");
}
else
{
printf("not loaded\n");
}
}
loading other images formats like png and Jpeg work properly but when trying to load an RGBA image I get the error "IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT". Could someone tell me if I am missing something or should add Some header to the RGBA image or should I call some more functions before opening an RGBA image?
If Imlib2 doesn't support reading RgbA images is there any alternative C-library that can read rgb image and do scaling like functions?
So this for if someone is facing the same issue
Thanks to #mark-setchell for contributing!!
magickcore Api is an alternative C-library that can be used to perform functions on raw RGB.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <magick/ImageMagick.h>
int main(int argc, char **argv)
{
ExceptionInfo
exception;
Image
*image,
*images,
*resize_image,
*thumbnails;
ImageInfo
*image_info;
/*
Initialize the image info structure and read an image.
*/
InitializeMagick(NULL);
GetExceptionInfo(&exception);
image_info = CloneImageInfo((ImageInfo *)NULL);
image_info->size = "1920x1080";
image_info->depth = 8;
(void)strcpy(image_info->filename, "image.rgba");
images = ReadImage(image_info, &exception);
if (images == (Image *)NULL)
exit(1);
resize_image = MinifyImage(images, &exception);
if (resize_image == (Image *)NULL)
printf("error \n");
DestroyImageInfo(image_info);
DestroyMagick();
return (0);
}
for reading raw images the depth and the WxH have to be specified for the image. the above is a very small example for reducing the size in half. (https://imagemagick.org/script/magick-core.php).

cvShowImage makes the system to throw exceptions

I have a code in C language that uses the cvopen Library.
Here is the code:
#include <stdio.h>
#include <opencv2\highgui\highgui_c.h>
int main(void)
{
int i;
cvNamedWindow("Display window", CV_WINDOW_AUTOSIZE); //create a window
//create an image
IplImage* image = cvLoadImage("C:\\Users\\magshimim\\Desktop\\Mummy.png", 1);
if (!image)//The image is empty.
{
printf("could not open image\n");
}
else
{
cvShowImage("Display window", image);
cvWaitKey(0);
system("pause");
cvReleaseImage(&image);
}
getchar();
return 0;
}
In line 17 "cvShowImage("Display window", image);" the system throws exception that says:
Exception thrown at 0xAD76406A in Q4.exe: 0xC0000008: An invalid handle was specified
The cvopen pack is fine, and other function works. but this code (which works on other computers) just crushes every time.
How can i fix this?
cvShowImage is part of the old C-style naming convention in OpenCV. This old convention has been fully depreciated and is not compatible with OpenCV 3.0 and up.
Instead of cvShowImage try using imshow
imshow("Display Window", image);

uEye Camera and OpenCV Memory Access

I am using a 35MM EO Megapixel Fixed FL Lens Edmund Optics camera, OpenCV 2.4.6, and Ubuntu 12.04 LTS as my development environment. I am also using C to develop, not C++. The camera has an API that I am following, and I believe I have set everything up correctly. I initialize the camera, set memory locations, and freeze the video. I then use OpenCV to get the image from memory, but my image is nothing like what it should be (may be seen below). Is my image data pulling data from a junk memory location? How can I access the image saved by "is_FreezeVideo" for image processing done by OpenCV? The image that is printed out can be seen here http://i.imgur.com/kW6aqB3.png
The code I am using is below.
#include "../Include/Camera.h"
#include <wchar.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
//#include <opencv2/opencv.hpp>
#include <ueye.h>
// uEye variables
HIDS m_hCam; // handle to room
HWND m_hWndDisplay; // handle to diplay window
int m_Ret; // return value of uEye SDK functions
int m_nColorMode = 0; // Y8/RGB16/RGB24/REG32
int m_nBitsPerPixel=8; // number of bits needed store one pixel
int m_nSizeX = 1280; // width of video
int m_nSizeY = 1024; // height of video
int m_lMemoryId; // grabber memory - buffer ID
char* m_pcImageMemory; // grabber memory - pointer to buffer
int m_nRenderMode = IS_RENDER_FIT_TO_WINDOW; //render mode
void getAzimuth(){
}
void getElevation(){
}
void initializeCamera(){
if (m_hCam !=0 ) {
//free old image mem.
is_FreeImageMem (m_hCam, m_pcImageMemory, m_lMemoryId);
is_ExitCamera (m_hCam);
}
// init room
m_hCam = (HIDS) 0; // open next room
m_Ret = is_InitCamera (&m_hCam, NULL); // init room
if (m_Ret == IS_SUCCESS) {
// retrieve original image size
SENSORINFO sInfo;
is_GetSensorInfo (m_hCam, &sInfo);
m_nSizeX = sInfo.nMaxWidth;
m_nSizeY = sInfo.nMaxHeight;
printf("Width: %d Height: ", m_nSizeX, m_nSizeY);
// setup the color depth to the current windows setting
is_GetColorDepth (m_hCam, &m_nBitsPerPixel, &m_nColorMode);
is_SetColorMode (m_hCam, m_nColorMode);
//printf ("m_nBitsPerPixel=%i m_nColorMode=%i \n", m_nBitsPerPixel, IS_CM_BAYER_RG8);
// memory initialization
is_AllocImageMem (m_hCam, m_nSizeX, m_nSizeY, m_nBitsPerPixel, &m_pcImageMemory, &m_lMemoryId);
//set memory active
is_SetImageMem (m_hCam, m_pcImageMemory, m_lMemoryId);
// display initialization
is_SetImageSize (m_hCam, m_nSizeX, m_nSizeY);
is_SetImagePos(m_hCam, 0, 0);
is_SetDisplayMode (m_hCam, IS_SET_DM_DIB);
} else {
printf("No Camera Initialized! %c", 10);
}
if (m_hCam !=0) {
INT dummy;
char *pMem, *pLast;
double fps = 0.0;
if (is_FreezeVideo (m_hCam, IS_WAIT) == IS_SUCCESS) {
m_Ret = is_GetActiveImageMem(m_hCam, &pLast, &dummy);
m_Ret = is_GetImageMem(m_hCam, (void**)&pLast);
}
IplImage* tmpImg = cvCreateImageHeader (cvSize (m_nSizeX, m_nSizeY), IPL_DEPTH_8U, 1);
tmpImg->imageData = &m_pcImageMemory;
cvNamedWindow("src",1);
cvShowImage("src",tmpImg);
cvWaitKey(0);
}
}
Thanks
You need to use is_ImageFile function to save the image file to a filename.You can see the sample example from the is_ImageFile function.You can save it to the format(bmp,png,jpeg) you need.
regards,
Sreenivas
The problem was the camera properties. After setting brightness and other properties, we now get an actual image

Screen shot program compiling issue

I am trying to get this screen shot program to work (below) which saves a picture of the screen as a bmp file and when I try to compile it using gcc, I get the following error:
/tmp/ccetmoRd.o:Screenshot.c:(.text+0x128): undefined reference to _GetDIBits#28'
/tmp/ccetmoRd.o:Screenshot.c:(.text+0x1e1): undefined reference to_GetDIBits#28'
collect2: ld returned 1 exit status
Any ideas why this may be?
Thanks a lot.
code:
#include <stdlib.h>
#include <windows.h>
#include <stdio.h>
void TakeScreenShot(char* filename);
int main()
{
TakeScreenShot("c:\\Screenshot.bmp");
return 0;
}
//
// Side Effects:N/A
//
//This code is copyrighted and has// limited warranties.Please see http://
// www.Planet-Source-Code.com/vb/scripts/Sh
// owCode.asp?txtCodeId=10754&lngWId=3//for details.//**************************************
//
void TakeScreenShot(char* filename)
{
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
HBITMAP h;
OpenClipboard(NULL);
h = (HBITMAP)GetClipboardData(CF_BITMAP);
CloseClipboard();
HDC hdc=NULL;
FILE*fp=NULL;
LPVOID pBuf=NULL;
BITMAPINFO bmpInfo;
BITMAPFILEHEADER bmpFileHeader;
do
{
hdc=GetDC(NULL);
ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
GetDIBits(hdc,h,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
if(bmpInfo.bmiHeader.biSizeImage<=0)
bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL)
{
MessageBox( NULL, "Unable to Allocate Bitmap Memory", "Error", MB_OK|MB_ICONERROR);
break;
}
bmpInfo.bmiHeader.biCompression=BI_RGB;
GetDIBits(hdc,h,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
if((fp = fopen(filename,"wb"))==NULL)
{
MessageBox(NULL, "Unable to Create Bitmap File", "Error", MB_OK|MB_ICONERROR);
break;
}
bmpFileHeader.bfReserved1=0;
bmpFileHeader.bfReserved2=0;
bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
bmpFileHeader.bfType='MB';
bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp);
}
while(0);
if(hdc)
ReleaseDC(NULL,hdc);
if(pBuf)
free(pBuf);
if(fp)
fclose(fp);
}
Since feature requests to mark a comment as an answer remain declined, I copy the above solution here.
SOLVED: Downloaded gdi32 library and it resolved the issue. Thanks for the tip! – Jeremy

screenshot using openGL and/or X11

i am trying to get a screenshot of the screen or a window. I tried using functions from X11
and it works fine. The problem is that getting the pixels from XImage takes a lot of time.
Than i tried to look for some answers on how to do it using openGL. Here's what i've got:
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
int main(int argc, char **argv)
{
int width=1200;
int height=800;
//_____________________________----
Display *dpy;
Window root;
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi;
GLXContext glc;
dpy = XOpenDisplay(NULL);
if ( !dpy ) {
printf("\n\tcannot connect to X server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);
if (!vi) {
printf("\n\tno appropriate visual found\n\n");
exit(0);
}
glXMakeCurrent(dpy, root, glc);
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));
//____________________________________________
glXMakeCurrent(dpy, root, glc);
glEnable(GL_DEPTH_TEST);
GLubyte* pixelBuffer = new GLubyte[sizeof(GLubyte)*width*height*3*3];
glReadBuffer(GL_FRONT);
GLint ReadBuffer;
glGetIntegerv(GL_READ_BUFFER,&ReadBuffer);
glPixelStorei(GL_READ_BUFFER,GL_RGB);
GLint PackAlignment;
glGetIntegerv(GL_PACK_ALIGNMENT,&PackAlignment);
glPixelStorei(GL_PACK_ALIGNMENT,1);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_INT, pixelBuffer);
int i;
for (i=0;i<100;i++) printf("%u\n",((unsigned int *)pixelBuffer)[i]);
return 0;
}
when i run the program it returns an error:
X Error of failed request: BadAccess (attempt to access private resource denied)
Major opcode of failed request: 199 ()
Minor opcode of failed request: 26
Serial number of failed request: 20
Current serial number in output stream: 20
if i comment the line with glXMakeCurrent(dpy, root, glc); before glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); it returns no erros, but all the pixels are 0.
How should i go about this problem? I am new to openGL and maybe i am missing something important here. Maybe also another way of getting pixels from the screen or specific window exists?
I don't think what you are trying to do is possible. You can't use OpenGL to read pixels from window you don't own and which probably don't even use OpenGL. You need to stick to X11.
If you have XImage you can get raw pixels from ximage->data. Just make sure you are reading it in correct format.
http://tronche.com/gui/x/xlib/graphics/images.html
You can use XShmGetImage, but you have to query the extensions of the X11 server first, to make sure MIT-SHM extension is available. You also need to know how to setup and use a shared memory segment for this.
Querying the Extension:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l224
Getting the image:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l537
The following runs once at 140 fps on my platform. xcb_image_get() (called with XCB_IMAGE_FORMAT_Z_PIXMAP) will store all pixels in ximg->data, pixel by pixel. On my platform, each pixel is 32 bits, each channel is 8 bits, and there's 3 channels (to 8 bits per pixel are unused).
/*
gcc ss.c -o ss -lxcb -lxcb-image && ./ss
*/
#include <stdio.h>
#include <xcb/xcb_image.h>
xcb_screen_t* xcb_get_screen(xcb_connection_t* connection){
const xcb_setup_t* setup = xcb_get_setup(connection); // I think we don't need to free/destroy this!
return xcb_setup_roots_iterator(setup).data;
}
void xcb_image_print(xcb_image_t* ximg){
printf("xcb_image_print() Printing a (%u,%u) `xcb_image_t` of %u bytes\n\n", ximg->height, ximg->width, ximg->size);
for(int i=0; i < ximg->size; i += 4){
printf(" ");
printf("%02x", ximg->data[i+3]);
printf("%02x", ximg->data[i+2]);
printf("%02x", ximg->data[i+1]);
printf("%02x", ximg->data[i+0]);
}
puts("\n");
}
int main(){
// Connect to the X server
xcb_connection_t* connection = xcb_connect(NULL, NULL);
xcb_screen_t* screen = xcb_get_screen(connection);
// Get pixels!
xcb_image_t* ximg = xcb_image_get(connection, screen->root, 0, 0, screen->width_in_pixels, screen->height_in_pixels, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
// ... Now all pixels are in ximg->data!
xcb_image_print(ximg);
// Clean-up
xcb_image_destroy(ximg);
xcb_disconnect(connection);
}

Resources