基于C++的图像边缘检测技术

本文介绍了一种基于Sobel算子和Laplacian算子进行彩色图像边缘检测的方法。通过这两种算子,可以实现对彩色图像的有效边缘提取,并支持灰度化、二值化等不同形式的输出。
.h
typedef struct ColorImageMes
{
RGBQUAD** BYImageData;    //彩色图像像素数据
double**  DOImageData;
_In_ int    Height;    //图像高
_In_ int    Width;     //图像宽
} ColorimageMes;

class ColorScaleHood : public CObject  
{
  public:
   void Color_Soble_Side(ColorImageMes source, ColorImageMes  &result, int Mode);
   void Color_Laplacian_Side(ColorImageMes source, ColorImageMes  &result, int mode);
};

.cpp
#include "Colorscale.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////
//基于Sble算子的边缘检测
**source:原彩图
**result:结果图
**m_nWidth:图像的宽
**m_nHeight:图像的高
**Mode;  0  灰度化
         1  二值化
**:status:finfish
///////////////////////////////////////////////////////////////////////////////////////////////////////
void ColorScaleHood::Color_Soble_Side(ColorImageMes source, ColorImageMes  &result, int Mode)
{
 int i, j, a, aHr, aHg, aHb, aVr, aVg, aVb, aH, aV;
 double scale = 1;   //1
 result.BYImageData = new RGBQUAD*[source.Height];
 result.BYImageData[0] = new RGBQUAD[source.Width];
 result.BYImageData[source.Height-1] = new RGBQUAD[source.Width];
 for (i = 1; i < source .Height- 1; i++)
 {
   result.BYImageData[i] = new RGBQUAD[source.Width];
  for (j = 1; j < source .Width- 1; j++)
  {
//计算红色分量水平灰度
    aHr = abs((source.BYImageData[i - 1][j - 1].rgbRed + source.BYImageData[i - 1][j].rgbRed * 2      +source.BYImageData[i - 1][j + 1].rgbRed) - (source.BYImageData[i + 1][j + 1].rgbRed + source.BYImageData[i + 1][j].rgbRed * 2 + source.BYImageData[i + 1][j - 1].rgbRed));
//计算红色分量垂直灰度
   aVr = abs((source.BYImageData[i - 1][j - 1].rgbRed + source.BYImageData[i][j - 1].rgbRed * 2 + source.BYImageData[i + 1][j - 1].rgbRed) - (source.BYImageData[i - 1][j + 1].rgbRed + source.BYImageData[i][j + 1].rgbRed * 2 + source.BYImageData[i + 1][j + 1].rgbRed));
//计算绿色分量水平灰度
   aHg = abs((source.BYImageData[i - 1][j - 1].rgbGreen + source.BYImageData[i - 1][j].rgbGreen * 2 + source.BYImageData[i - 1][j + 1].rgbGreen) - (source.BYImageData[i + 1][j + 1].rgbGreen + source.BYImageData[i + 1][j].rgbGreen * 2 + source.BYImageData[i + 1][j - 1].rgbGreen));
//计算绿色分量垂直灰度
   aVg = abs((source.BYImageData[i - 1][j - 1].rgbGreen + source.BYImageData[i][j - 1].rgbGreen * 2 + source.BYImageData[i + 1][j - 1].rgbGreen) - (source.BYImageData[i - 1][j + 1].rgbGreen + source.BYImageData[i][j + 1].rgbGreen * 2 + source.BYImageData[i + 1][j + 1].rgbGreen));
//计算蓝色分量水平灰度
   aHb = abs((source.BYImageData[i - 1][j - 1].rgbBlue + source.BYImageData[i - 1][j].rgbBlue * 2 + source.BYImageData[i - 1][j + 1].rgbBlue) - (source.BYImageData[i + 1][j + 1].rgbBlue + source.BYImageData[i + 1][j].rgbBlue * 2 + source.BYImageData[i + 1][j - 1].rgbBlue));
//计算蓝色分量垂直灰度
   aVb = abs((source.BYImageData[i - 1][j - 1].rgbBlue + source.BYImageData[i][j - 1].rgbBlue * 2 + source.BYImageData[i + 1][j - 1].rgbBlue) - (source.BYImageData[i - 1][j + 1].rgbBlue + source.BYImageData[i][j + 1].rgbBlue * 2 + source.BYImageData[i + 1][j + 1].rgbBlue));
//计算水平综合灰度差
   aH = aHr + aHg + aHb;
//计算垂直综合灰度差
   aV = aVr + aVg + aVb;
 if (1)
    {
      if (aH > aV)
        a = aH;
      else
        a = aV;
     }
    else
     a = (aH + aV) / 2;

     a = a*scale;
     switch (Mode)
     {
        case 0:a = a > 255 ? 255 : a; break; //灰度化
        case 1:a = a > 255 ? 0 : 255; break; //二值化  255为白色,0为黑色  
        default:a = a > 255 ? 255 : a; break; //灰度化
     }
     result.BYImageData[i][j].rgbBlue = result.BYImageData[i][j].rgbGreen =
     result.BYImageData[i][j].rgbRed = a;
 }
}
      result.Height = source.Height;
      result.Width = source.Width;
}
///////////////////////////////////////////////////
//基于拉布拉斯算子的边缘检测
**source:原彩图
**result:结果图
**m_nWidth:图像的宽
**m_nHeight:图像的高
**mode:0   显示正边缘
       1   显示负边缘
  2   显示所有边缘
  3   对比两种边缘
**255为白色,0为黑色
**:status:finfish
////////////////////////////////////////////////////////////////////////
void ColorScaleHood::Color_Laplacian_Side(ColorImageMes source, ColorImageMes  &result,int mode)
{
   int templt[9] = { 1, 1, 1, 1, -8, 1, 1, 1, 1 };    //正向模板
   double scale = 1;
   int i, j, a,n;
   int x, y;
  GrayImageMes Result;

  Result.ImageData = new BYTE*[source.Height];
  result.BYImageData = new RGBQUAD*[source.Height];
  for (int L = 0; L
  {
    result.BYImageData[L] = new RGBQUAD[source.Width];
    Result.ImageData[L] = new BYTE[source.Width];
 }
    CGrayscaleHood temp;
    temp.weighting_color_to_grayscale(source, Result);     //转化为灰度
    for (i = 1; i < source.Height - 1; i++)
   {
        for (j = 1; j < source.Width - 1; j++)
        {
            for (n = 0; n < 9; n++)
            {
               x = 1 - n / 3;
               y = 1 - n + (n / 3) * 3;
              a += Result.ImageData[i - x][j - y] * templt[n];
             }
                     a *= scale;
                     a = a > 255 ? 255 : a;
                     a = a < -255 ? -255 : a; 
               switch (mode)
              {
                        case 0:if (a < 0)a = 0; break;
                        case 1:if (a > 0)a = 0; 
                                                 a=-a;
                                                 break;
                         case 2:if (a < 0)a = -a; break;
                         case 3:a = 128 + a / 2;  break;
}
            result.BYImageData[i][j].rgbBlue = result.BYImageData[i][j].rgbGreen = 
            result.BYImageData[i][j].rgbRed = a;
        }
  }
    result.Height = source.Height;
    result.Width = source.Width;

   delete Result.ImageData;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值