02-25-2016 08:09 AM - edited 02-25-2016 08:10 AM
Hello. I want to convert an image, acquired from webcam, to grayscale in C, using myRIO. I have a webcam connected to myRIO, simple image acquisition is working, but I cannot find a solution to convert the image to grayscale. I don't get any errors at Building or at Run Configuration.
This is the image written in folder: (black)
The code is here:
#include <stdio.h> #include <stdbool.h> #include "MyRio.h" #include <nivision.h> #include <NIIMAQdx.h> #define CAM_NAME "cam1" #define CAPTURED_IMAGE_PATH "./capturedImage4.png" #define WINDOW_NUMBER 15 // Image Display Window Number #define IMAQDX_ERROR_MESSAGE_LENGTH 256 bool Log_Vision_Error(int errorValue); bool Log_Imaqdx_Error(IMAQdxError errorValue); int main(int argc, char **argv) { #if 1 NiFpga_Status status; printf("\n ++ ImageAcquisitionAndDisplayExample \n"); Image* captureImage = NULL; Image* processedImage; IMAQdxSession session = 0; /* * Open the myRIO NiFpga Session. * This function MUST be called before all other functions. After this call * is complete the myRIO target will be ready to be used. */ status = MyRio_Open(); if (MyRio_IsNotSuccess(status)) { return status; } // Create the Image Buffer captureImage = imaqCreateImage(IMAQ_IMAGE_HSL, 0); processedImage = imaqCreateImage(IMAQ_IMAGE_HSL, 0); imaqSetImageSize(processedImage, 640, 480); // Open a session to the selected camera if (Log_Imaqdx_Error(IMAQdxOpenCamera(CAM_NAME, IMAQdxCameraControlModeController, &session))) goto cleanup; // Acquire an image if (Log_Imaqdx_Error(IMAQdxSnap(session, captureImage))) goto cleanup; // Process the Captured image here. // Grayscale if (Log_Imaqdx_Error(imaqExtractColorPlanes(captureImage, 1, NULL, NULL, processedImage ))) goto cleanup; // Write the captured image to the file Log_Vision_Error(imaqWriteVisionFile(processedImage, CAPTURED_IMAGE_PATH, NULL)); cleanup: //Close the Camera session IMAQdxCloseCamera (session); // Dispose the image imaqDispose(captureImage); imaqDispose(processedImage); printf("\n -- ImageAcquisitionAndDisplayExample \n"); return 0; status = MyRio_Close(); #endif } bool Log_Imaqdx_Error(IMAQdxError errorValue) { if (errorValue) { char errorText[IMAQDX_ERROR_MESSAGE_LENGTH]; IMAQdxGetErrorString(errorValue, errorText, IMAQDX_ERROR_MESSAGE_LENGTH); printf("\n %s ", errorText); return true; } return false; } // Print the VISION Error Message bool Log_Vision_Error(int errorValue) { if ( (errorValue != TRUE) && (imaqGetLastError() != ERR_SUCCESS)) { char *tempErrorText = imaqGetErrorText(imaqGetLastError()); printf("\n %s ", tempErrorText); imaqDispose(tempErrorText); return true; } return false; }
Solved! Go to Solution.
02-26-2016 06:14 PM
To be clear, by "simple image acquisition is working," you mean you can get regular images to save to disk using the Snap and appear as you'd like. It's not until you run this line:
if (Log_Imaqdx_Error(imaqExtractColorPlanes(captureImage, 1, NULL, NULL, processedImage ))) goto cleanup;
that you run into any issues? At that point, you only pull out the all black image?
I know you're trying to use C. But, why don't we take a quick look at an example in LabVIEW? Check out this KB: http://digital.ni.com/public.nsf/allkb/ED42C55C29B9B34C862570A60079952E While the language is different, we're looking at the same general API and we should be able to figure out what's going on and translate that to C for you.
In the VI Snippet, we start by creating an image buffer named "orig" and read from a file path to fill that image buffer. We also create an image buffer for the HSL data type. That allows us to pull the Hue, Saturation, and Luminance planes rather than the RGB planes.
From there, we cast the image in "orig" to the HSL type and place it in the "hsl" buffer. We pass this modified image to the Extract Color Planes VI. At this point, we extract the Luminance plane and get something grayscale from there.
Also, check out this document: http://www.ni.com/pdf/manuals/322567a.pdf It provides information about all of the potential calls. On page 2-20, it discusses the imaqExtractColorPlanes function call.
int = imaqExtractColorPlanes(const Image* image, ColorMode mode, Image* plane1, Image* plane2, Image* plane3)
Looking at your call, that means
image = captureImage
mode = 1
plane1 = NULL
plane2 = NULL
plane 3 = processedImage
In the documentation for mode, "The color space from which the function extracts the planes. Valid options are IMAQ_RGB, IMAQ_HSL, IMAQ_HSV, and IMAQ_HSI. For more information about color spaces, see the IMAQ Vision User Manual." Let's try changing that away from 1 to being one of those types. It looks like you're trying to use 1 in place of IMAQ_HSL and pull the third plane as the luminance plane. Is that correct?
03-01-2016 08:54 AM
BoKnows wrote:
To be clear, by "simple image acquisition is working," you mean you can get regular images to save to disk using the Snap and appear as you'd like. It's not until you run this line:
if (Log_Imaqdx_Error(imaqExtractColorPlanes(captureImage, 1, NULL, NULL, processedImage ))) goto cleanup;
that you run into any issues? At that point, you only pull out the all black image?
Yes, without this part of code, I can get a regular image and it appear on the disk. After I insert that code, I get the black image.
BoKnows wrote:
In the documentation for mode, "The color space from which the function extracts the planes. Valid options are IMAQ_RGB, IMAQ_HSL, IMAQ_HSV, and IMAQ_HSI. For more information about color spaces, see the IMAQ Vision User Manual." Let's try changing that away from 1 to being one of those types. It looks like you're trying to use 1 in place of IMAQ_HSL and pull the third plane as the luminance plane. Is that correct?
Sorry for this, I forgot to modify the code that I uploaded here. In Eclipse it was correct written, like this:
if (Log_Imaqdx_Error(imaqExtractColorPlanes(captureImage, IMAQ_HSL, NULL, NULL, processedImage ))) goto cleanup;I put the 1 instead of IMAQ_HSL only to see what happens and I forgot to change back. But id doesn't work neither this way with IMAQ_HSL, I get the same black image.
About, LabVIEW, I understand what you say, I also made a VI to see what functions are used:
Here I saw the imaqExtractColorPlanes planes and I searched it in Vision's Help. I still don't understand why is not working because it's the same code translated from LabVIEW to C.
03-02-2016 04:45 PM
The LabVIEW code you posted doesn't include anything to send the image to a file. I'm curious if we're running into issues at this stage. If we comment out the code to convert to greyscale, does the original image write to the file correctly or are you only viewing it in the tests where you say it works?
I'm assuming the LabVIEW code you posted works to complete the task. It's slightly different than what I posted. But, as long as things are working I'm not too concerned with that.
03-03-2016 02:57 PM
@BoKnows wrote:The LabVIEW code you posted doesn't include anything to send the image to a file. I'm curious if we're running into issues at this stage. If we comment out the code to convert to greyscale, does the original image write to the file correctly or are you only viewing it in the tests where you say it works?
I'm assuming the LabVIEW code you posted works to complete the task. It's slightly different than what I posted. But, as long as things are working I'm not too concerned with that.
The code works now. The problem was here:
if (Log_Imaqdx_Error(imaqExtractColorPlanes(captureImage, 1, NULL, NULL, processedImage )))
Instead of Log_Imaqdx_Error, it must be Log_Vision_Error.