自己最好的canny实现(c#)

 

 第一张是原图,第二张是这个最好canny结果图

//1,拷贝8位数组图像

 byte[] jinzita1024 = new byte[1024 * 768]

int hh = 768;
            int ww = 1024;第一张

            for (int j = 0; j < hh; j++)
                for (int i = 0; i < ww; i++)
                {
                    jinzita1024[j * ww + i] = glob_buffer8[j * ww  +  i];
                }

 double[] tiduhe;
            tiduhe = new double[ww * hh];
            double[] gy = new double[ww * hh];
            double[] gx = new double[ww * hh];
            double[] angle = new double[ww * hh];

  double[] CA_tempImage33gaos = new double[ww * hh];
            /2,高斯平滑
            for (int j = 1; j < (hh - 1); j++)
            {
                for (int i = 1; i < (ww - 1); i++)
                {
                    int n0 = (j * ww + i);
                    CA_tempImage33gaos[n0] = (jinzita1024[n0 - ww - 1] + 2 * jinzita1024[n0 - ww] + jinzita1024[n0 - ww + 1] +
                                            2 * jinzita1024[n0 - 1] + 4 * jinzita1024[n0] + 2 * jinzita1024[n0 + 1] +
                                            jinzita1024[n0 + ww - 1] + 2 * jinzita1024[n0 + ww] + jinzita1024[n0 + ww + 1]) / 16.0;
                }
            }

 for (int i = 1; i < (hh - 1); i++)
            {
                for (int j = 1; j < (ww - 1); j++)
                {
                    // 3,此处改为 sobelx,sobely20220327
                    double Grady = CA_tempImage33gaos[(i - 1) * ww + j - 1] + 2 * CA_tempImage33gaos[(i - 1) * ww + j] + CA_tempImage33gaos[(i - 1) * ww + j + 1]
                        - CA_tempImage33gaos[(i + 1) * ww + j - 1] - 2 * CA_tempImage33gaos[(i + 1) * ww + j] - CA_tempImage33gaos[(i + 1) * ww + j + 1]
                        ;


                    double Gradx = CA_tempImage33gaos[(i - 1) * ww + j + 1] + 2 * CA_tempImage33gaos[i * ww + j + 1] + CA_tempImage33gaos[(i + 1) * ww + j + 1]
                         - CA_tempImage33gaos[(i - 1) * ww + j - 1] - 2 * CA_tempImage33gaos[i * ww + j - 1] - CA_tempImage33gaos[(i + 1) * ww + j - 1];

                    tiduhe[i * ww + j] = Math.Sqrt(Gradx * Gradx + Grady * Grady);
                    // 4,这个函数博客里边有jiaoduAndxiangxian
                    angle[i * ww + j] = jiaoduAndxiangxian(Gradx, Grady) * 180 / Math.PI;//角度

                    gx[i * ww + j] = Gradx;
                    gy[i * ww + j] = Grady;
                }
            }5,非极大值抑制

  double g1 = 0, g2 = 0, g3 = 0, g4 = 0;
            double dTmp1 = 0.0, dTmp2 = 0.0;
            double dWeight = 0.0;
            double[] img_N = new double[ww * hh];
            for (int i = 1; i < (ww - 1); i++)
            {
                for (int j = 1; j < (hh - 1); j++)
                {
                    int fangbian = j * ww + i;
                    if (tiduhe[fangbian] == 0)
                    {
                        img_N[fangbian] = 0;
                    }
                    else
                    {

                        //材///   
                        ///       g1  g2                  /   
                        ///           C                   /   
                        ///           g4  g3              /   
                        ///   
                        if (((angle[fangbian] >= 45) && (angle[fangbian] < 90)) ||
                            ((angle[fangbian] >= 225) && (angle[fangbian] < 270)))//
                        {

                            g1 = tiduhe[fangbian - ww - 1];
                            g2 = tiduhe[fangbian - ww];
                            g4 = tiduhe[fangbian + ww];
                            g3 = tiduhe[fangbian + ww + 1];
                        //    if (gy[fangbian] != 0)//为什么这个是多余的?
 
                       //     {
                                dWeight = Math.Abs(gx[fangbian] / (gy[fangbian])); //  p->Gradx,q->Grady
                                dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                                dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                     //       }
                      //      else { }
                        }
                        材///   
                        /               g1                      /   
                        /       g4  C   g2              /   
                        /       g3              /   
                        / 
                        //   else
                        if (((angle[fangbian] >= 135) && (angle[fangbian] < 180)) ||//shuipingfangxiang
                                ((angle[fangbian] >= 315) && (angle[fangbian] < 360)))//20220817
                        {   //int nPointIdx = i+j*w;

                            g3 = tiduhe[fangbian + ww - 1];
                            g2 = tiduhe[fangbian + 1];
                            g1 = tiduhe[fangbian - ww + 1];
                            g4 = tiduhe[fangbian - 1];
                       //     if (gx[fangbian] != 0)//为什么这个是多余的?
                     //       {
                                dWeight = Math.Abs(gy[fangbian] / (gx[fangbian]));   //  p->Gradx,q->Grady
                                dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                                dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                        //    }
                          //  else
                        //    {
                                //先不处理20220817
                        //    }

                        }
                        材///   
                        /           g2  g1              /   
                        /           C                   /   
                        /       g3  g4                  /   
                        /   
                        //else 
                        if (((angle[fangbian] >= 90) && (angle[fangbian] <135)) ||
                                 ((angle[fangbian] >= 270) && (angle[fangbian] < 315))) //20220817
                        {  //int nPointIdx = i+j*w;
                            g2 = tiduhe[fangbian - ww];
                            g1 = tiduhe[fangbian - ww + 1];
                            g4 = tiduhe[fangbian + ww];
                            g3 = tiduhe[fangbian + ww - 1];
                         //   if (gy[fangbian] != 0)//为什么这个是多余的?
 
                          //  {
                                dWeight = Math.Abs(gx[fangbian] / (gy[fangbian]));  //  p->Gradx,q->Grady
                                dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                                dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                         // }
                          //  else { }
                        }
                        //材///   
                        ///       g3              /   
                        ///       g4  C   g2              /   
                        ///               g1                      /   
                        /// 
                        //else 

                        if (((angle[fangbian] >= 0) && (angle[fangbian] < 45)) ||
                      ((angle[fangbian] >= 180) && (angle[fangbian] < 225)))//这个是45度方向
                        {  //一共四个方向,已经判断了3个方向,这个可以不必判断了
                            g1 = tiduhe[fangbian + ww + 1];
                            g2 = tiduhe[fangbian + 1];
                            g3 = tiduhe[fangbian - ww - 1];
                            g4 = tiduhe[fangbian - 1];
                           // if (gx[fangbian] != 0)//为什么这个是多余的?
 
                          //  {
                                dWeight = Math.Abs(gy[fangbian] / (gx[fangbian]));    //  
                                dTmp1 = g1 * dWeight + g2 * (1 - dWeight);
                                dTmp2 = g3 * dWeight + g4 * (1 - dWeight);
                           // }
                         //   else { }
                        }

                    }
                    if ((tiduhe[fangbian] >= dTmp1) && (tiduhe[fangbian] >= dTmp2))
                    {
                        img_N[fangbian] = tiduhe[fangbian];//梯度图像
                   
                    }
                    else
                    {
                        img_N[fangbian] = 0;

                    }
                }
            }

以上是canny最关键的处理已经结束了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C#实现模板匹配的基本步骤: 1. 引用HALCON的类库。 2. 对实时采集目标的图像进行二值化和图像增强处理。 3. 创建模板,可以是本地图片,也可以是当前采集视频画面的截图。 4. 对模板进行规范化的选取和操作步骤。 5. 将处理好的待测目标的图像与模板进行匹配,提取目标的形状、角度和匹配得分等参数。 6. 最后使用C#对匹配结果进行处理和显示。 以下是一个简单的C#模板匹配的代码示例: ```csharp // 引用HALCON的类库 using HalconDotNet; // 读取模板图像和待测图像 HObject modelImage, testImage; HOperatorSet.ReadImage(out modelImage, "modelImage.jpg"); HOperatorSet.ReadImage(out testImage, "testImage.jpg"); // 对待测图像进行二值化和图像增强处理 HObject binImage, enhanceImage; HOperatorSet.Threshold(testImage, out binImage, 128, 255); HOperatorSet.EdgesSubPix(binImage, out enhanceImage, "canny", 1, 20, 40); // 创建模板 HObject modelRegion; HOperatorSet.Threshold(modelImage, out modelRegion, 128, 255); // 对模板进行规范化的选取和操作步骤 HObject normModelRegion; HOperatorSet.NormalizeImage(modelRegion, out normModelRegion); // 将处理好的待测目标的图像与模板进行匹配 HObject resultRegion; HTuple angle, score; HOperatorSet.FindShapeModel(enhanceImage, normModelRegion, (new HTuple(0)).TupleRad(), (new HTuple(360)).TupleRad(), 0.5, 1, 0.5, "least_squares", 0, 0.7, out resultRegion, out angle, out score); // 显示匹配结果 HObject displayImage; HOperatorSet.DispObj(testImage, windowHandle); HOperatorSet.SetColor(windowHandle, "red"); HOperatorSet.DispObj(resultRegion, windowHandle); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值