Halcon产品圆缺陷检测VC源码

Halcon产品圆缺陷检测VC源码

#include "HalconCpp.h"
#include <math.h>
using namespace Halcon;
Hobject pImage;

void inspect_bottle_mouth(unsigned int nSmoothX,float* information)
{
  using namespace Halcon;

  // Local iconic variables
  Hobject  Image, ImageSmooth, Rectangle, ImageReduced;
  Hobject  Regions, DarkRegion, RegionOpening, RegionClosing;
  Hobject  RegionFillUp, RegionBorder, RegionDilation, Edges;
  Hobject  ContoursSplit, UnionContours, LongestContour, Circle;
  Hobject  RegionErosion, RegionDifference, ImageReduced1;
  Hobject  ImagePolar, ImagePart,ImageScaleMax, ImageMean, Connection1;
  Hobject  SelectedRegions, RegionUnion, XYTransRegion;


  // Local control variables
  HTuple  StoreEmptyRegion, WindowHandle1, Index;
  HTuple  Width, Height, Number, area1, Row1, Column1, Length;
  HTuple  Row, Column, Radius, StartPhi, EndPhi, PointOrder;

    //用递归过滤器平滑图像
    smooth_image(pImage, &ImageSmooth, "gauss", 0.3);
    //获取图像的尺寸
    get_image_size(ImageSmooth, &Width, &Height);

/*    //创建一个平行于坐标轴的矩形
    gen_rectangle1(&Rectangle, 50, 100, Height, Width-80);
    //图像与区域结合,选取矩形内的区域作为ROI
    reduce_domain(ImageSmooth, Rectangle, &ImageReduced);
    //利用形态学原理检测螺母
    //分割图像,选取灰度值在 80~255 之间的区域
    //threshold (ImageReduced, Regions, 140, 255)
    threshold(ImageReduced, &Regions, 80, 255);      */
    
    
    //分割图像,选取灰度值在 80~255 之间的区域
    threshold(ImageSmooth, &Regions, 80, 255);
    //从对象数组中选择区域,对象数组的编号可以通过函数count_obj询问
    //count_obj (Regions, Number)
    select_obj(Regions, &DarkRegion, 1);
    //消除噪点
    opening_circle(DarkRegion, &RegionOpening, 3.5);
    //填充缺口
    closing_circle(RegionOpening, &RegionClosing, 30);
    //填充孔洞
    fill_up(RegionClosing, &RegionFillUp);
    //获取区域的中心
    area_center(RegionFillUp, &area1, &Row1, &Column1);
    //减少其边界区域,boundary函数将返回区域的边界轮廓
    boundary(RegionFillUp, &RegionBorder, "outer");
    //对区域的边界轮廓进行膨胀操作
    dilation_circle(RegionBorder, &RegionDilation, 3.5);
    //图像与区域结合,选取膨胀操作后的边界轮廓内的区域作为ROI
    reduce_domain(pImage, RegionDilation, &ImageReduced);
    //通过边缘检测得出基圆并获知圆心,形成检测基圆。
    //使用Deriche,兰瑟,沉,或Canny算子滤波器提取图像边缘
    edges_sub_pix(ImageReduced, &Edges, "canny", 0.5, 20, 40);
    //将轮廓分割成直线、圆和椭圆
    segment_contours_xld(Edges, &ContoursSplit, "lines_circles", 5, 4, 2);
    //合并属于同一个圆的区域
    union_cocircular_contours_xld(ContoursSplit, &UnionContours, 0.9, 0.5, 0.5, 200,
        50, 50, "true", 1);
    //获取等高线或多边形的长度
    length_xld(UnionContours, &Length);
    //从对象数组中选择区域,对象数组的编号可以通过函数count_obj询问
    select_obj(UnionContours, &LongestContour, HTuple((Length.SortIndex())[(Length.Num())-1])+1);
    //拟合出检测基圆,该函数返回每一个外形的中心,半径。['ahuber'有利于减小极端值的影响]
    fit_circle_contour_xld(LongestContour, "ahuber", -1, 0, 0, 3, 2, &Row, &Column,
        &Radius, &StartPhi, &EndPhi, &PointOrder);
    // stop(); only in hdevelop
    //定义检测区域(可根据实际情况调整大小),将环形检测区域转换成矩形检测区域,便于后续处理
    //根据检测基圆的中心和半径画圆
    //gen_circle (Circle, Row, Column, Radius+20)
     gen_circle(&Circle, Row1, Column1, 350);

    //基于圆结构元素的膨胀操作
    dilation_circle(Circle, &RegionDilation, 3);
    //基于圆结构元素的腐蚀操作
    erosion_circle(Circle, &RegionErosion, 148);
    //比较膨胀操作和腐蚀操作后的两幅图像
    difference(RegionDilation, RegionErosion, &RegionDifference);
    //图像与区域结合,选取闭操作之后的区域作为ROI
    reduce_domain(pImage, RegionDifference, &ImageReduced1);
    //极坐标变换图像,极坐标变换通常被用来矫正图像中的圆形物体或被包含在圆环中的物体
    //polar_trans_image (ImageReduced1, ImagePolar, Row, Column, 6.28*(Radius+50), Radius+100)
    // polar_trans_image(ImageReduced1, &ImagePolar, Row1, Column1, 6.28*(330+50), 330+100);
    polar_trans_image(ImageReduced1, &ImagePolar, Row1, Column1, 6.28*(360+50), 360+100);
//找到缺陷
    
    // 选取即将作极坐标逆变换的区域
     crop_part(ImagePolar, &ImagePart, 360-148, 0, 6.28*(360+50), 148);
    //最大灰度值扩散的数值范围在0到255。
//    scale_image_max(ImagePolar, &ImageScaleMax);
     scale_image_max(ImagePart, &ImageScaleMax);
    //平滑平均
    mean_image(ImageScaleMax, &ImageMean, nSmoothX, 7);
    //阀值分割
//    dyn_threshold(ImageScaleMax, ImageMean, &Regions, 22, "dark");
    dyn_threshold(ImageScaleMax, ImageMean, &Regions, 23, "dark");
    //去除噪点
    opening_circle(Regions, &RegionOpening, 2);
    //connection:把多个region连接记起来
    connection(RegionOpening, &Connection1);
    //根据特性选择区域
    select_shape(Connection1, &SelectedRegions, "area", "and", 360, 99999);
    //联合区域
    union1(SelectedRegions, &RegionUnion);
    //将矩形检测区域转换成环形,使之与被检测物同时显示[极坐标逆变换]
    //polar_trans_region_inv (RegionUnion, XYTransRegion, Row, Column, 6.28319, 1.367, 0, Radius-80, 6.28*Radius, 100, 1280, 1024, 'nearest_neighbor')
    //polar_trans_region_inv (RegionUnion, XYTransRegion, Row1, Column1, 6.28319, 1.367, 0, 100, 5.65*Radius, 100, 1280, 1024, 'nearest_neighbor')
/*     polar_trans_region_inv(RegionUnion, &XYTransRegion, Row1, Column1, 6.28319, 1.367,
        0, 100, 5.65*330, 100, 1280, 1024, "nearest_neighbor");   */
    /*polar_trans_region_inv(RegionUnion, &XYTransRegion, Row1, Column1, 6.28319, 0,
        340-148, 360, 7.15*360, 125, 1280, 1024, "nearest_neighbor");*/
    polar_trans_region_inv(RegionUnion, &XYTransRegion, Row1, Column1, 6.28319, 0,
        340-148, 340, 7.15*360, 125, 1280, 1024, "nearest_neighbor");
    
    //显示结果
    count_obj(RegionUnion, &Number);

    Hobject Image3;
    gen_image_const(&Image3, "byte",Width, Height);
    if(Number >0)
    {
        paint_region(XYTransRegion, Image3, &pImage, 255, "fill");  // 若图片有缺陷,则以“白色”显示缺陷
    }
    else
    {
        copy_image(Image3,&pImage);  //  若图片没有缺陷,则用自己创建的黑色背景覆盖图像区域
    }
}

//extern "C" _declspec(dllexport) unsigned int HCExportImage(unsigned char *pImageData,unsigned int nWidth,unsigned int nHeight,unsigned int nSmoothX,unsigned int nThresholdOffset, unsigned int nMinDefectSize)
extern "C" _declspec(dllexport) unsigned int HCExportImage(unsigned char *pImageData,unsigned int nWidth,unsigned int nHeight,unsigned int nSmoothX,float *coordinate)
{
    using namespace Halcon;

    HTuple Rows,Colomns;
    Hobject ImageResult;
    long    Width1, Height1;
    char    type[128];
    unsigned char* Pointer;

    unsigned char *pImageDataForProcess = NULL;
    
    pImageDataForProcess=new unsigned char[nWidth*nHeight];
    
    CopyMemory(pImageDataForProcess,pImageData,nWidth*nHeight);

    gen_image1(&pImage,"byte",nWidth,nHeight,(long)pImageDataForProcess);
    inspect_bottle_mouth(nSmoothX,coordinate);
    get_image_pointer1(pImage, (long*)&Pointer, type, &Width1, &Height1);

    CopyMemory(pImageData, Pointer, Width1*Height1);
    
    delete[] pImageDataForProcess;
    
    return 1;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

!chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值