Visual C++

我的代码是基于Paul Oh教授的教程。

你需要注意,当跟进这个教程的时候,一些必要的文件也许不再正常连接或丢失,他们可以在下面的位置下载。

qcsdk.exe

qc543enu.exe

根据 TRIPOD 的教程的说明,可以在其源程序中插入一段用户自己的图像处理代码,在这里,我插入了下面的代码:


void CTripodDlg::doMyImageProcessing(LPBITMAPINFOHEADER lpThisBitmapInfoHeader)
{
 // doMyImageProcessing:  This is where you'd write your own image processing code
 // Task: Read a pixel's grayscale value and process accordingly

 unsigned int W, H;   // Width and Height of current frame [pixels]
 unsigned int    row, col;  // Pixel's row and col positions
 unsigned long   i;   // Dummy variable for row-column vector
 unsigned int max_row;  // Row of the brightest pixel
 unsigned int max_col;  // Column of the brightest pixel
        BYTE  max_val = 0;         // Value of the brightest pixel

 // Values used for calculating range from captured image data
 // these values are only for a specific camera and laser setup
 const double gain = 0.0024259348; // Gain Constant used for converting
      // pixel offset to angle in radians
 const double offset = -0.056514344; // Offset Constant
 const double h_cm = 5.842;  // Distance between center of camera and laser
        double  range;          // Calculated range
 unsigned int pixels_from_center; // Brightest pixel location from center
      // not bottom of frame
 
 char  str[80];         // To print message
 CDC  *pDC;   // Device context need to print message

RoboticFan

        W = lpThisBitmapInfoHeader->biWidth; // biWidth: number of columns
        H = lpThisBitmapInfoHeader->biHeight; // biHeight: number of rows
 
 for (row = 0; row < H; row++) {
  for (col = 0; col < W; col++) {

   // Recall each pixel is composed of 3 bytes
   i = (unsigned long)(row*3*W + 3*col);
   
   // If the current pixel value is greater than any other, it is the new max pixel
   if (*(m_destinationBmp + i) >= max_val)
   {
    max_val = *(m_destinationBmp + i);
    max_row = row;
    max_col = col;
   }

  }
 }
 // After each frame, reset max pixel value to zero
        max_val = 0;

 for (row = 0; row < H; row++) {
  for (col = 0; col < W; col++) {

   i = (unsigned long)(row*3*W + 3*col);
   
   // Draw a white cross-hair over brightest pixel in the output display
   if ((row == max_row) || (col == max_col))
    *(m_destinationBmp + i) =
    *(m_destinationBmp + i + 1) =
    *(m_destinationBmp + i + 2) = 255;

  }
 }

 // Calculate distance of brightest pixel from center rather than bottom of frame
        pixels_from_center = 120 - max_row;

 // Calculate range in cm based on bright pixel location, and setup specific constants
 range = h_cm / tan(pixels_from_center * gain + offset);

 // To print message at (row, column) = (75, 580)
 pDC = GetDC(); 

 // Display frame coordinates as well as calculated range
 sprintf(str, "Max Value at x= %u, y= %u, range= %f cm    ",max_col, max_row, range);
 pDC->TextOut(75, 580, str);
 ReleaseDC(pDC);
}


完整的代码可以在下面下载到:
LaserRange.zip

可执行文件可在下面下载到:
LaserRange.exe

注意,为了执行这个文件,你可能需要qcsdk和qc543这两个驱动文件。

下面是摄像头激光测距仪的工作截图,注意它是如何工作的。在第二个例子中,有两个激光点,其中的一个是激光点在摄像头里面的反射,这个反射点由于没有那么强烈的,所以不适用于运算法则。



将来的工作

一个重要的改进就是将点改为线,这样可以计算每个光柱的距离而不是单个的光柱。这样的设置可以使车辆能够探测最大的前进距离,同样的,障碍物的最小距离也可以被探测到。