Docstoc

hsv

Document Sample
hsv Powered By Docstoc
					Studio di Consulenza
Bernardotti Flavio
Alessandria


Skype : Flavio58
Site : www.bernardotti.it
FaceBook : Flavio Bernardotti


NOTE E ROUTINE

Machine Vision Underwater
Our vision system is written in C++ and utilizes the open source OpenCV and libdc1394 libraries.
The vision system allows the mission to enable and disable the various different vision algorithms
whenever visual data is required for a specific mission element.
All of the machine vision algorithms work in a similar manner. The input image is converted from
RGB space into HSV space and split into its three component channels: hue, saturation, and
value. Each of these channels is segmented through predetermined thresholds, and the three
segmented channels are recombined to form a binary image. Contours are detected in the
binary image, and these contours are then run through a set of probabilistic filters and
moment analyses to determine the location, orientation, and probability for a specific mission
element. For reference, output from the shape detection algorithm is shown below (input image,
binary segmented image, and detected contours):




In the past, each of our vision algorithms was implemented in its own daemon. We now use an
integrated vision daemon which combines all the separate processing daemons currently used (such
as the pipe daemon, the buoy daemon, etc) and the camera capture daemon into one streamlined,
multithreaded daemon. Each processing daemon now becomes a ‘module’ that fits into a framework
provided by the camera daemon. These modules are dynamically loaded and unloaded, depending
on shared variables. Separate threads are used for each module and each capture source. Capture
sources can be physical cameras, directories of images, or video files. Images captured by the
daemon are no longer saved to disk and passed through paths stored in shared variables. Now,
images are passed in memory utilizing the module framework, resulting in significant performance
improvements.



// Create a HSV image from the RGB image using the full 8-bits, since OpenCV
only allows Hues up to 180 instead of 255.
// ref: http://"http://cs.haifa.ac.il/hagit/..._convert.html"
// Remember to free the generated HSV image.
IplImage* convertImageRGBtoHSV(const IplImage *imageRGB)
{
        float fR, fG, fB;
        float fH, fS, fV;
        const float FLOAT_TO_BYTE = 255.0f;
        const float BYTE_TO_FLOAT = 1.0f / FLOAT_TO_BYTE;

        // Create a blank HSV image
        IplImage *imageHSV = cvCreateImage(cvGetSize(imageRGB), 8, 3);
        if (!imageHSV || imageRGB->depth != 8 || imageRGB->nChannels != 3) {
                printf("ERROR in convertImageRGBtoHSV()! Bad input image.\n");
                exit(1);
        }

        int h = imageRGB->height;                // Pixel height.
        int w = imageRGB->width;                 // Pixel width.
        int rowSizeRGB = imageRGB->widthStep;    // Size of row in bytes,
including extra padding.
        char *imRGB = imageRGB->imageData;       // Pointer to the start of the
image pixels.
        int rowSizeHSV = imageHSV->widthStep;    // Size of row in bytes,
including extra padding.
        char *imHSV = imageHSV->imageData;       // Pointer to the start of the
image pixels.
        for (int y=0; y<h; y++) {
                for (int x=0; x<w; x++) {
                         // Get the RGB pixel components. NOTE that OpenCV
stores RGB pixels in B,G,R order.
                         uchar *pRGB = (uchar*)(imRGB + y*rowSizeRGB + x*3);
                         int bB = *(uchar*)(pRGB+0);     // Blue component
                         int bG = *(uchar*)(pRGB+1);     // Green component
                         int bR = *(uchar*)(pRGB+2);     // Red component

                        //   Convert from 8-bit integers to floats.
                        fR   = bR * BYTE_TO_FLOAT;
                        fG   = bG * BYTE_TO_FLOAT;
                        fB   = bB * BYTE_TO_FLOAT;

                        // Convert from RGB to HSV, using float ranges 0.0 to
1.0.
                        float fDelta;
                        float fMin, fMax;
                        int iMax;
                        // Get the min and max, but use integer comparisons
for slight speedup.
                        if (bB < bG) {
                                if (bB < bR) {
                                        fMin = fB;
                                        if (bR > bG)   {
                                                iMax   = bR;
                                                fMax   = fR;
                                        }
                                        else {
                                                iMax   = bG;
                                                fMax   = fG;
                                        }
                                }
                                else {
                                        fMin = fR;
                                        fMax = fG;
                                        iMax = bG;
                                }
                        }
                        else {
                                 if (bG < bR) {
                                         fMin = fG;
                                         if (bB > bR)   {
                                                 fMax   = fB;
                                                 iMax   = bB;
                                         }
                                         else {
                                                 fMax   = fR;
                                                 iMax   = bR;
                                         }
                                 }
                                 else {
                                         fMin = fR;
                                         fMax = fB;
                                         iMax = bB;
                                 }
                        }
                        fDelta = fMax - fMin;
                        fV = fMax;                              // Value
(Brightness).
                        if (iMax != 0) {                        // Make sure
its not pure black.
                                fS = fDelta / fMax;             // Saturation.
                                float ANGLE_TO_UNIT = 1.0f / (6.0f * fDelta);
// Make the Hues between 0.0 to 1.0 instead of 6.0
                                if (iMax == bR) {               // between
yellow and magenta.
                                        fH = (fG - fB) * ANGLE_TO_UNIT;
                                }
                                else if (iMax == bG) {          // between
cyan and yellow.
                                        fH = (2.0f/6.0f) + ( fB - fR ) *
ANGLE_TO_UNIT;
                                }
                                else {                          // between
magenta and cyan.
                                        fH = (4.0f/6.0f) + ( fR - fG ) *
ANGLE_TO_UNIT;
                                }
                                // Wrap outlier Hues around the circle.
                                if (fH < 0.0f)
                                        fH += 1.0f;
                                if (fH >= 1.0f)
                                        fH -= 1.0f;
                        }
                        else {
                                // color is pure Black.
                                fS = 0;
                                fH = 0; // undefined hue
                        }

                        // Convert from floats to 8-bit integers.
                        int bH = (int)(0.5f + fH * 255.0f);
                        int bS = (int)(0.5f + fS * 255.0f);
                        int bV = (int)(0.5f + fV * 255.0f);

                        // Clip the values to make sure it fits within the
8bits.
                        if (bH > 255)
                                bH = 255;
                        if (bH < 0)
                                bH = 0;
                           if (bS > 255)
                                   bS = 255;
                           if (bS < 0)
                                   bS = 0;
                           if (bV > 255)
                                   bV = 255;
                           if (bV < 0)
                                   bV = 0;

                           // Set the HSV pixel components.
                           uchar *pHSV = (uchar*)(imHSV + y*rowSizeHSV + x*3);
                           *(pHSV+0) = bH;         // H component
                           *(pHSV+1) = bS;         // S component
                           *(pHSV+2) = bV;         // V component
                }
        }
        return imageHSV;
}


// Create an RGB image from the HSV image using the full 8-bits, since OpenCV
only allows Hues up to 180 instead of 255.
// ref: http://"http://cs.haifa.ac.il/hagit/..._convert.html"
// Remember to free the generated RGB image.
IplImage* convertImageHSVtoRGB(const IplImage *imageHSV)
{
        float fH, fS, fV;
        float fR, fG, fB;
        const float FLOAT_TO_BYTE = 255.0f;
        const float BYTE_TO_FLOAT = 1.0f / FLOAT_TO_BYTE;

        // Create a blank RGB image
        IplImage *imageRGB = cvCreateImage(cvGetSize(imageHSV), 8, 3);
        if (!imageRGB || imageHSV->depth != 8 || imageHSV->nChannels != 3) {
                printf("ERROR in convertImageHSVtoRGB()! Bad input image.\n");
                exit(1);
        }

        int h = imageHSV->height;                       // Pixel height.
        int w = imageHSV->width;                        // Pixel width.
        int rowSizeHSV = imageHSV->widthStep;           // Size of row in
bytes, including extra padding.
        char *imHSV = imageHSV->imageData;              // Pointer to the
start of the image pixels.
        int rowSizeRGB = imageRGB->widthStep;           // Size of row in
bytes, including extra padding.
        char *imRGB = imageRGB->imageData;              // Pointer to the
start of the image pixels.
        for (int y=0; y<h; y++) {
                for (int x=0; x<w; x++) {
                        // Get the HSV pixel components
                        uchar *pHSV = (uchar*)(imHSV + y*rowSizeHSV + x*3);
                        int bH = *(uchar*)(pHSV+0);     // H component
                        int bS = *(uchar*)(pHSV+1);     // S component
                        int bV = *(uchar*)(pHSV+2);     // V component

                           //   Convert from 8-bit integers to floats
                           fH   = (float)bH * BYTE_TO_FLOAT;
                           fS   = (float)bS * BYTE_TO_FLOAT;
                           fV   = (float)bV * BYTE_TO_FLOAT;

                           // Convert from HSV to RGB, using float ranges 0.0 to
1.0
                        int iI;
                        float fI, fF, p, q, t;

                        if( bS == 0 ) {
                                // achromatic (grey)
                                fR = fG = fB = fV;
                        }
                        else {
                                // If Hue == 1.0, then wrap it around the
circle to 0.0
                                if (fH >= 1.0f)
                                        fH = 0.0f;

                                fH *= 6.0;                         // sector 0 to
5
                                fI = floor( fH );                  // integer
part of h (0,1,2,3,4,5 or 6)
                                iI = (int) fH;                     //
"               "               "                  "
                                fF = fH - fI;                      // factorial
part of h (0 to 1)

                                p = fV * ( 1.0f - fS );
                                q = fV * ( 1.0f - fS * fF );
                                t = fV * ( 1.0f - fS * ( 1.0f - fF ) );

                                switch( iI ) {
                                        case 0:
                                                   fR = fV;
                                                   fG = t;
                                                   fB = p;
                                                   break;
                                        case 1:
                                                   fR = q;
                                                   fG = fV;
                                                   fB = p;
                                                   break;
                                        case 2:
                                                   fR = p;
                                                   fG = fV;
                                                   fB = t;
                                                   break;
                                        case 3:
                                                   fR = p;
                                                   fG = q;
                                                   fB = fV;
                                                   break;
                                        case 4:
                                                   fR = t;
                                                   fG = p;
                                                   fB = fV;
                                                   break;
                                        default:                   // case 5 (or
6):
                                                   fR = fV;
                                                   fG = p;
                                                   fB = q;
                                                   break;
                                }
                        }

                        // Convert from floats to 8-bit integers
                        int bR = (int)(fR * FLOAT_TO_BYTE);
                            int bG = (int)(fG * FLOAT_TO_BYTE);
                            int bB = (int)(fB * FLOAT_TO_BYTE);

                            // Clip the values to make sure it fits within the
8bits.
                            if (bR > 255)
                                    bR = 255;
                            if (bR < 0)
                                    bR = 0;
                            if (bG > 255)
                                    bG = 255;
                            if (bG < 0)
                                    bG = 0;
                            if (bB > 255)
                                    bB = 255;
                            if (bB < 0)
                                    bB = 0;

                         // Set the RGB pixel components. NOTE that OpenCV
stores RGB pixels in B,G,R order.
                         uchar *pRGB = (uchar*)(imRGB + y*rowSizeRGB + x*3);
                         *(pRGB+0) = bB;         // B component
                         *(pRGB+1) = bG;         // G component
                         *(pRGB+2) = bR;         // R component
                }
        }
        return imageRGB;
}



IplImage *imHSV;
imHSV = convertRGBtoHSV(imRGB); // Allocates a new HSV image.
... do stuff with imHSV ...
cvReleaseImage(&imHSV);         // Frees the new HSV image.
cvReleaseImage(&imRGB);         // Frees the original RGB image.



http://www.mip.informatik.uni-kiel.de/~wwwadmin/Software/

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:19
posted:12/10/2010
language:Italian
pages:6
Flavio Bernardotti Flavio Bernardotti Ing. www.bernardotti.it/portal
About Computer consultant since 1984. I wrote the software ITALINK (1985) to create the italian FIDONET (with some other sysop). I wrote 14 books all free distributed with fidonet, usenet and internet (http://www.bernardotti.it). For other info see my site.