Question

I made a simple graphical user interface with Qt and I use OpenCV for making processing on webcam streaming, i.e canny edge detection.

I try to implement a switch between two displays of the webcam :

1*) "normal Mode" : a grayscale display where webcam gives a border detection video with grayscale color

2*) "greenMode" : a green and black display where webcam gives the same "border detected" but with green and black colors.

The first one works (with grayscale) works. Here's the result :

enter image description here

Now I have problems with the second one. Here's the part of the code where I can't find a solution :

  // Init capture
  capture = cvCaptureFromCAM(0);
  first_image = cvQueryFrame( capture );
  // Init current qimage
  current_qimage = QImage(QSize(first_image->width,first_image->height),QImage::Format_RGB32);

  IplImage* frame = cvQueryFrame(capture);
  int w = frame->width;
  int h = frame->height;

  if (greenMode) // greenMode : black and green result
  {
    current_image = cvCreateImage(cvGetSize(frame),8,3); 
    cvCvtColor(frame,current_image,CV_BGR2RGB);

    for(int j = 0; j < h; j++)
    {  
      for(int i = 0; i < w; i++)
      {
        current_qimage.setPixel(i,j,qRgb(current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1]));
      }
    }
  }
  else // normal Mode : grayscale result WHICH WORKS
  {
    current_image = cvCreateImage(cvGetSize(frame),8,1); 
    cvCvtColor(frame,current_image,CV_BGR2GRAY);

    for(int j = 0; j < h; j++)
    {  
      for(int i = 0; i < w; i++)
      {
        current_qimage.setPixel(i,j,qRgb(current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1]));

      }
    }
  }
  gaussianfilter(webcam_off);
  border_detect(webcam_off);
  cvReleaseImage(&current_image);
  repaint();

The "greenMode" doesn't seem to put good pixels with this "setPixel" (I take the middle rgb value : current_image->imageData[i+j*w+1]) :

current_image = cvCreateImage(cvGetSize(frame),8,3); 
    cvCvtColor(frame,current_image,CV_BGR2RGB);

    for(int j = 0; j < h; j++)
    {  
      for(int i = 0; i < w; i++)
      {
        current_qimage.setPixel(i,j,qRgb(current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1]));
      }
    }

Here's what I get :

enter image description here

Firstly, the output is not green and black and secondly, it's zoomed compared to the grayscale image.

Could you have any clues to get the greenMode ?

Was it helpful?

Solution

qRgb(current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1],current_image->imageData[i+j*w+1])

You're using an identical value for all three RGB color components. R == G == B will always result in grey.

To convert an RGB value to green/black, you could for example convert to greyscale (using the luminosity method) and then tint it green:

const int v = qRound(  0.21 * pixel.red() + 0.71 * pixel.green() + 0.07 * pixel.blue() );
setPixel( i, j, qRgb( v, 0, 0 ) );

(There are probably more sophisticated methods for the tinting).

For the scaling, I assume the error occurs when calculating the index for current_image. You're using the same (i+j*w+1) for both images, but the grey has 1 channel and the second 3 (third cvCreateImage argument). So the latter will have two more values per pixel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top