最近刚刚接触图形方面的东西,真是一无所知:)
我现在想做的就是扫描图像或者曲线,然后判断图中的像素之间的夹角,然后得出链码的数字串值
但是由于不懂图形方面的编程技术,对于怎样取得图中像素和像素的位置都不清楚
请高手指点迷津,帮我如一下门,或者介绍相关比较基础的网站或书籍也好,多谢:)

解决方案 »

  1.   

    这里有我写的一个程序,是.Net平台下C++的,你可以看看:/******************************************************************************
     函数名称: Trace
     输入参数: bmpIn        —— Image类对象,包含要处理图像的所有信息 
                rgbEdge      —— 边缘颜色
    ptStart      —— 跟踪起始点
     输出参数: alEdgePoints —— 边缘点记录
                alCode       —— 边缘点链码
                bmpOut       —— Image类对象,传出跟踪得到的边缘,边缘用黑色表示
     返回值  : 成功返回true,失败返回false
     功能描述: 边缘跟踪(跟踪最外层边缘)
     其它说明: 1.程序会生成一个新的Bitmap对象bmpOut,请注意释放            
                2.输入图像必须是边缘检测后的图象,否则该函数会得到错误结果
                3.输入图像要求是二值图像
    4.链码的方向如下
                  2
      3   |   1
            \ | /
       4------+------0
            / | \
      5   |   7
          6
    ******************************************************************************/
    bool EdgeContour::Trace(Bitmap* bmpIn, Bitmap** bmpOut, 
    ArrayList** alEdgePoints, ArrayList** alCodes,
    Point ptStart, Color rgbEdge)
    {
    // 检查输入参数
    if(bmpIn == NULL || ptStart.X < 0 || ptStart.Y < 0)
    {
    return false;
    } // 循环变量
    int x;
    int y;
    int r; // 存储颜色信息的中间变量
    PixelData* pPixelIn;    // 输入象素地址
    PixelData* pPixelOut;   // 输出象素地址 // 临时变量
    Color rgbIn1;
    Color rgbIn2;
    Color rgbTemp;
    Color rgbOut; // 当前扫描点
    Point ptCurPoint;  // 方向数组
    int nCurDirection;
    int nDirection __nogc[8][2] = {{ 1, 0}, { 1, -1}, {0, -1}, {-1, -1}, 
                                   {-1, 0}, {-1,  1}, {0,  1}, { 1,  1}}; // 扫描结束标志
    bool bFindStartPoint;
    bool bFindDirection; // 图像的宽度与高度
    int nWidth  = bmpIn->Width;
    int nHeight = bmpIn->Height; // 待返回的位图对象
    (*bmpOut) = new Bitmap(nWidth, nHeight, bmpIn->PixelFormat); // 将图像锁定到内存
    BitmapMemory* bmpMemIn  = new BitmapMemory(bmpIn);
    BitmapMemory* bmpMemOut = new BitmapMemory((*bmpOut)); bmpMemIn->LockBitmap();
    bmpMemOut->LockBitmap(); // 检查输入参数
    if(ptStart.X < 0 || ptStart.X >= nWidth ||
       ptStart.Y < 0 || ptStart.Y >= nHeight)
    {
    return false;
    } // 将返回位图初始化为白色
    // 每行
    for(y = 0; y < nHeight; y++)
    {
    // 获取该行首象素颜色值
    pPixelOut = bmpMemOut->PixelAt(0, y); // 每列
    for(x = 0; x < nWidth; x++)
    {
    // 填充白色  
    pPixelOut->byRed   = 255;
    pPixelOut->byGreen = 255;
    pPixelOut->byBlue  = 255; pPixelOut++;
    }
    } pPixelOut = bmpMemOut->PixelAt(ptStart.X, ptStart.Y);
    pPixelOut->byRed   = 0;
    pPixelOut->byGreen = 0;
    pPixelOut->byBlue  = 0; // 初始化链表
    __box Point* ptCurBox;
    (*alEdgePoints) = new ArrayList();
    (*alCodes)      = new ArrayList(); // 初始化当前扫描点
    ptCurPoint.X = ptStart.X;
    ptCurPoint.Y = ptStart.Y; // 加入第一个点
    ptCurBox = __box(ptCurPoint);
    (*alEdgePoints)->Add(ptCurBox); // (1)确定初始方向
    r = 0;
    bFindDirection = false;
    nCurDirection  = 0;
    while(!bFindDirection)
    {
    pPixelIn = bmpMemIn->PixelAt(ptCurPoint.X + nDirection[nCurDirection][0], 
                             ptCurPoint.Y + nDirection[nCurDirection][1]);
    rgbIn1 = Color::FromArgb(pPixelIn->byRed, pPixelIn->byGreen, pPixelIn->byBlue); pPixelIn = bmpMemIn->PixelAt(ptCurPoint.X + nDirection[(nCurDirection + 1) % 8][0], 
                             ptCurPoint.Y + nDirection[(nCurDirection + 1) % 8][1]);
    rgbIn2 = Color::FromArgb(pPixelIn->byRed, pPixelIn->byGreen, pPixelIn->byBlue); if(rgbIn1.ToArgb() == rgbEdge.ToArgb() && 
       rgbIn2.ToArgb() != rgbEdge.ToArgb())
    {
    bFindDirection = true;
    }
    else
    {
    r++;
    nCurDirection = (nCurDirection + 1) % 8; // 防止死循环
    if(r > 8)
    {
    return false;
    }
    }
    } // 修改当前点
    ptCurPoint.X += nDirection[nCurDirection][0];
    ptCurPoint.Y += nDirection[nCurDirection][1]; bFindStartPoint = false;
    do{
    // 加入第i+1个点(i=1,2,...)
    ptCurBox = __box(ptCurPoint);
    (*alEdgePoints)->Add(ptCurBox); // 加入第i个链码(i=1,2,...)
    (*alCodes)->Add(__box(nCurDirection)); // (2)保存当前点,为目标点着色
    pPixelOut = bmpMemOut->PixelAt(ptCurPoint.X, ptCurPoint.Y);
    pPixelOut->byRed   = 0;
    pPixelOut->byGreen = 0;
    pPixelOut->byBlue  = 0;; // (4)根据当前点与方向查找下一个边界点
    nCurDirection = (nCurDirection + 1) % 8;     // 逆时针旋转45度 pPixelIn = bmpMemIn->PixelAt(ptCurPoint.X + nDirection[nCurDirection][0], 
                             ptCurPoint.Y + nDirection[nCurDirection][1]);
    rgbTemp = Color::FromArgb(pPixelIn->byRed, pPixelIn->byGreen, pPixelIn->byBlue);

    if(rgbTemp.ToArgb() != rgbEdge.ToArgb())
    {
    // 当前点为白色
    // 顺时针旋转45度
    nCurDirection = (nCurDirection + 7) % 8; // 初始化
    bFindDirection = false; while(!bFindDirection)
    {
    pPixelIn = bmpMemIn->PixelAt(ptCurPoint.X + nDirection[nCurDirection][0], 
                             ptCurPoint.Y + nDirection[nCurDirection][1]);
    rgbIn1 = Color::FromArgb(pPixelIn->byRed, pPixelIn->byGreen, pPixelIn->byBlue);

    if(rgbIn1.ToArgb() == rgbEdge.ToArgb())
    {
    // 修改当前点
    ptCurPoint.X += nDirection[nCurDirection][0];
    ptCurPoint.Y += nDirection[nCurDirection][1]; bFindDirection = true;
    }
    else
    {
    // 顺时针旋转45度
    nCurDirection = (nCurDirection + 7) % 8;
    }                
    }
    }
    else
    {
    // 当前点为黑色
    // 逆时针旋转45度
    nCurDirection = (nCurDirection + 1) % 8; // 初始化
    bFindDirection = false; while(!bFindDirection)
    {
    pPixelIn = bmpMemIn->PixelAt(ptCurPoint.X + nDirection[nCurDirection][0], 
                             ptCurPoint.Y + nDirection[nCurDirection][1]);
    rgbIn2 = Color::FromArgb(pPixelIn->byRed, pPixelIn->byGreen, pPixelIn->byBlue); if(rgbIn2.ToArgb() != rgbEdge.ToArgb())
    {
    // 回退操作
    nCurDirection = (nCurDirection + 7) % 8; // 修改当前点
    ptCurPoint.X += nDirection[nCurDirection][0];
    ptCurPoint.Y += nDirection[nCurDirection][1]; bFindDirection = true;
    }
    else
    {
    // 逆时针旋转45度
    nCurDirection = (nCurDirection + 1) % 8;
    }                
    }
    } // (3)判断是否结束
    if(ptCurPoint == ptStart)
    {
    bFindStartPoint = true; // 加入最后一个链码
    (*alCodes)->Add(__box(nCurDirection)); break;
    } }while(!bFindStartPoint); // 解锁图像
    bmpMemIn->UnlockBitmap();
    bmpMemOut->UnlockBitmap(); // 成功
    return true;
    }