精华内容
下载资源
问答
  • opencv检测划痕

    千次阅读 2017-09-07 11:44:25
    小的特征提取,例如金属表面的划痕、丝网的漏洞等。本例提取丝网上漏洞区域以及漏洞数量,主要步骤如下: 1.对读入的图像进行动态阈值分割,分割出Blob区域。 2.利用面积对Blob区域进行选择。 3


    在实际应用中,得到的图像的阈值不太理想时通过固定阈值分割很难得到所要提取的特征,因此Halcon中
    含有动态阈值分割法,即首先对图像进行均值滤波,然后与现有图像最差后进行阈值分割。该方法适合比较
    小的特征提取,例如金属表面的划痕、丝网的漏洞等。

    本例提取丝网上漏洞区域以及漏洞数量,主要步骤如下:
    1.对读入的图像进行动态阈值分割,分割出Blob区域。
    2.利用面积对Blob区域进行选择。
    3.显示检测结果。

    对下图的长短划痕进行检测,结果如图所示
    原图
    结果
    检测结果

    展开全文
  • 图像划痕识别,增加长度,宽度识别等功能,使用OPECV3.2.1库
  • opencv划痕缺陷检测

    2021-06-15 14:10:39
    检测思路 ① 原图均值滤波 ② 滤波图像与原图进行差分 ③ 二值化 ④ 查找轮廓(根据轮廓长度进行筛选) 代码

    检测思路

    ① 原图均值滤波

    ② 滤波图像与原图进行差分

    ③ 二值化

    ④ 查找轮廓(根据轮廓长度进行筛选)

    代码

    import cv2
    import numpy as np
    
    print(cv2.__version__)
    minThres = 6
    
    # 读取图像1
    img1 = cv2.imread('C:\\Users\\PC\\Desktop\\surface_scratch.png')
    img2 = cv2.imread('C:\\Users\\PC\\Desktop\\surface_scratch.png')
    
    # 中值滤波
    img1 = cv2.medianBlur(img1, 15)
    
    # 图像差分
    diff = cv2.absdiff(img1, img2)
    cv2.imshow('diff', diff)  # 结果图
    
    gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
    # 二值化
    _, thres = cv2.threshold(gray, minThres, 255, cv2.THRESH_BINARY)
    cv2.imshow('thres', thres)
    
    # 查找轮廓
    contours, hierarchy = cv2.findContours(thres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    # 输出轮廓个数
    print(len(contours))
    
    for i in range(0, len(contours)):
        length = cv2.arcLength(contours[i], True)
        # 通过轮廓长度筛选
        if length > 30:
            cv2.drawContours(img2, contours[i], -1, (0, 0, 255), 2)
    
    cv2.imshow('result', img2)  # 结果图
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    效果

    展开全文
  • C++ OpenCV实现3. 结果展示:总结 前言 1. 2. C++ OpenCV实现 #include <opencv2\imgcodecs.hpp> #include <opencv2\core.hpp> #include <opencv2\imgproc.hpp> #include <opencv2\highgui....


    前言

    最近在51Halcon中看到一条有意思的求助帖子,有热心朋友给出了Halcon的解决方法,这里给出C++ OpenCV的解决方法。


    1. 检测步骤

    Halcon实现(引用https://www.51halcon.com/thread-1173-1-2.html):
    请添加图片描述
    看到检测图像以及想要检测的目标(绿色实线闭合区域),我们知道,要检测的区域的区分度不高,这里给出个人实现思路:检测区域位于圆形的中心,而圆形中心区域亮度比周边要高,我们可以先分割出中心亮度高的区域,然后在这一分割出的区域进行检测目标,提取出目标轮廓。

    2. C++ OpenCV实现

    #include <opencv2\imgcodecs.hpp>
    #include <opencv2\core.hpp>
    #include <opencv2\imgproc.hpp>
    #include <opencv2\highgui.hpp>
    #include <vector>
    
    using namespace cv;
    
    int main()
    {
    	std::string strImgFile = "C:\\Temp\\common\\Workspace\\Opencv\\images\\detect_defect_with_complex_background.bmp";
    	Mat mSrc = imread(strImgFile);
    	CV_Assert(!mSrc.empty());
    
    	Mat mGray;
    	cvtColor(mSrc, mGray, COLOR_BGR2GRAY);
    	CV_Assert(!mGray.empty());
    
    	Mat mThresh;
    	threshold(mGray, mThresh, 0, 255, THRESH_BINARY | THRESH_OTSU);
    	CV_Assert(!mThresh.empty());
    
    	imshow("thresh", mThresh);
    
    	Mat mCenterLightArea;
    	threshold(mGray, mCenterLightArea, 200, 255, THRESH_BINARY);
    	CV_Assert(!mCenterLightArea.empty());
    
    	imshow("center", mCenterLightArea);
    
    	Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11));
    	Mat mOpen;
    	morphologyEx(mCenterLightArea, mOpen, MORPH_OPEN, kernel);
    	CV_Assert(!mOpen.empty());
    
    	imshow("open1", mOpen);
    
    	morphologyEx(mOpen, mOpen, MORPH_DILATE, kernel, Point(-1, -1), 7);
    	 
    	imshow("open2", mOpen); 
    
    	std::vector<std::vector<Point>> contours;
    	findContours(mOpen, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    	Point2f center = { 0 };
    	float	radius = 0;
    
    	for (int i = 0; i < contours.size(); i++)
    	{
    		Point2f tempCenter = { 0 };
    		float tempRadius = 0;
    		minEnclosingCircle(contours[i], tempCenter, tempRadius);
    
    		if (tempRadius > radius)
    		{
    			radius = tempRadius;
    			center = tempCenter;
    		}
    	}
    
    	Mat mMask = Mat::zeros(mOpen.size(), mOpen.type());
    	CV_Assert(!mMask.empty());
    
    	circle(mMask, Point(int(center.x + 0.5), int(center.y + 0.5)), int(radius + 0.5), 255, -1);
    
    	imshow("mask", mMask);
    
    	Mat mCenterArea = mGray & mMask;
    	CV_Assert(!mCenterArea.empty());
    
    	imshow("center", mCenterArea);
    
    	Mat mResult;
    	threshold(mCenterArea, mResult, 10, 255, THRESH_BINARY_INV | THRESH_OTSU);
    	CV_Assert(!mResult.empty());
    	imshow("result", mResult);
    
    	contours.clear();
    	findContours(mResult, contours, RETR_TREE, CHAIN_APPROX_NONE);
    
    	for (int i = 0; i < contours.size(); i++)
    	{
    		double area = contourArea(contours[i]);
    		if (area > 1000 && area < 10000)
    		{
    			drawContours(mSrc, contours, i, Scalar(0, 0, 255));
    		}
    	}
    
    	imshow("Final Result", mSrc);
    
    	waitKey(0);
    	destroyAllWindows();
    
    	system("pause");
    	return 0;
    }
    

    3. 结果展示:

    原图:
    请添加图片描述

    OpenCV实现:
    在这里插入图片描述

    Halcon实现(引用https://www.51halcon.com/thread-1173-1-2.html):
    请添加图片描述


    总结

    本人的方法,只针对特定的原始图像,没法验证通用性,个人感觉很繁琐,没有Halcon简单方便,如果有大神提供简单的OpenCV实现方法,欢迎赐教,谢谢!

    参考

    https://www.51halcon.com/thread-1173-1-2.html

    展开全文
  • 基于OpenCv的金属表面划痕检测

    千次阅读 2019-02-15 09:04:36
    在实际应用中,得到的...小的特征提取,例如金属表面的划痕、丝网的漏洞等。 本例提取丝网上漏洞区域以及漏洞数量,主要步骤如下: 1.对读入的图像进行动态阈值分割,分割出Blob区域。 2.利用面积对Blob区域进行...

     

    在实际应用中,得到的图像的阈值不太理想时通过固定阈值分割很难得到所要提取的特征,因此Halcon中 
    含有动态阈值分割法,即首先对图像进行均值滤波,然后与现有图像做差后进行阈值分割。该方法适合比较 
    小的特征提取,例如金属表面的划痕、丝网的漏洞等。

    本例提取丝网上漏洞区域以及漏洞数量,主要步骤如下: 
    1.对读入的图像进行动态阈值分割,分割出Blob区域。 
    2.利用面积对Blob区域进行选择。 
    3.显示检测结果。

    对下图的长短划痕进行检测,结果如图所示 

    åå¾

    结果 

    æ£æµç»æ

    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    int main()
    {
        cv::Mat image,imagemean,diff,Mask;
        image = cv::imread("huahen.png");
        blur(image,imagemean,Size(13,13));
        subtract(imagemean,image,diff);
        threshold(diff, Mask, 5, 255, THRESH_BINARY_INV);
        imshow("imagemean",imagemean);
        imshow("diff",diff);
        imshow("Mask",Mask);
        Mat imagegray;
        cvtColor(Mask,imagegray,CV_RGB2GRAY);
        vector<vector<Point>> contours;
        vector<Vec4i> hierarchy;
        findContours(imagegray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
        Mat drawing = Mat::zeros(Mask.size(), CV_8U);
        int j=0;
        for (int i = 0; i<contours.size();i++)
        {
            Moments moms = moments(Mat(contours[i]));
            double area = moms.m00;
    
            if (area > 20 && area < 1000)
            {
                drawContours(drawing, contours, i, Scalar(255), FILLED, 8, hierarchy, 0, Point());
                j = j + 1;
             }
    
        }
    
        Mat element15(3, 3, CV_8U, Scalar::all(1));
        Mat close;
        morphologyEx(drawing, close, MORPH_CLOSE, element15);
        imshow("drawing", drawing);
    
    
        vector<vector<Point> > contours1;
        vector<Vec4i> hierarchy1;
        findContours(close, contours1, hierarchy1, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
            imshow("close", close);
            j = 0;
            int m = 0;
            for (int i = 0; i < contours1.size(); i++)
            {
                Moments moms = moments(Mat(contours1[i]));
                double area = moms.m00;//零阶矩即为二值图像的面积  double area = moms.m00;
                //如果面积超出了设定的范围,则不再考虑该斑点
    
                double area1 = contourArea(contours1[i]);
                if (area > 50 && area < 100000)
                {
                    drawContours(image, contours1, i, Scalar(0, 0, 255), FILLED, 8, hierarchy1, 0, Point());
                    j = j + 1;
    
                }
                else if (area >= 0 && area <= 50)
                {
                    drawContours(image, contours1, i, Scalar(255, 0, 0), FILLED, 8, hierarchy1, 0, Point());
                    m = m + 1;
    
                }
            }
    
            char t[256];
                snprintf(t, j,"%01d");
                string s = t;
                string txt = "Long NG : " + s;
                putText(image, txt, Point(20, 30), CV_FONT_HERSHEY_COMPLEX, 1,
                    Scalar(0, 0, 255), 2, 8);
    
                snprintf(t, m,"%01d");
                s = t;
                txt = "Short NG : " + s;
                putText(image, txt, Point(20, 60), CV_FONT_HERSHEY_COMPLEX, 1,
                    Scalar(255, 0, 0), 2, 8);
            imshow("漏洞", image);
    
    
    
    
    
        cv::waitKey(0);
    
    
    }
    

     

    * This programm shows the extraction of surface scratches via
    * local thresholding and morphological post-processing
    * 
    dev_update_off ()
    dev_close_window ()
    * 
    * Step 1: Acquire image
    * 
    read_image (Image, 'surface_scratch')
    get_image_size (Image, Width, Height)
    dev_open_window_fit_image (Image, 0, 0, Width, Width, WindowID)
    set_display_font (WindowID, 16, 'mono', 'true', 'false')
    dev_set_draw ('margin')
    dev_set_line_width (4)
    dev_display (Image)
    Message := 'This program shows the extraction of'
    Message[1] := 'surface scratches via local thresholding'
    Message[2] := 'and morphological post-processing'
    disp_message (WindowID, Message, 'window', 12, 12, 'black', 'true')
    disp_continue_message (WindowID, 'black', 'true')
    stop ()
    * 
    * Step 2: Segment image
    * 
    * Using a local threshold
    mean_image (Image, ImageMean, 7, 7)
    dyn_threshold (Image, ImageMean, DarkPixels, 5, 'dark')
    * 
    * Extract connected components
    connection (DarkPixels, ConnectedRegions)
    dev_set_colored (12)
    dev_display (Image)
    dev_display (ConnectedRegions)
    Message := 'Connected components after image segmentation'
    Message[1] := 'using a local threshold.'
    disp_message (WindowID, Message, 'window', 12, 12, 'black', 'true')
    disp_continue_message (WindowID, 'black', 'true')
    stop ()
    * 
    * Step 3: Process regions
    * 
    * Select large regions
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10, 1000)
    dev_display (Image)
    dev_display (SelectedRegions)
    disp_message (WindowID, 'Large Regions', 'window', 12, 12, 'black', 'true')
    disp_continue_message (WindowID, 'black', 'true')
    stop ()
    * 
    * Visualize fractioned scratch
    open_zoom_window (0, round(Width / 2), 2, 303, 137, 496, 3, WindowHandleZoom)
    dev_set_color ('blue')
    dev_display (Image)
    dev_display (SelectedRegions)
    set_display_font (WindowHandleZoom, 16, 'mono', 'true', 'false')
    disp_message (WindowHandleZoom, 'Fractioned scratches', 'window', 12, 12, 'black', 'true')
    disp_continue_message (WindowHandleZoom, 'black', 'true')
    stop ()
    * 
    * Merge fractioned scratches via morphology
    union1 (SelectedRegions, RegionUnion)
    dilation_circle (RegionUnion, RegionDilation, 3.5)
    dev_display (Image)
    dev_display (RegionDilation)
    Message := 'Region of the scratches after dilation'
    disp_message (WindowHandleZoom, Message, 'window', 12, 12, 'black', 'true')
    disp_continue_message (WindowHandleZoom, 'black', 'true')
    stop ()
    skeleton (RegionDilation, Skeleton)
    connection (Skeleton, Errors)
    dev_set_colored (12)
    dev_display (Image)
    dev_display (Errors)
    Message := 'Fractioned scratches merged via morphology'
    disp_message (WindowHandleZoom, Message, 'window', 12, 12, 'black', 'true')
    disp_continue_message (WindowHandleZoom, 'black', 'true')
    stop ()
    * 
    * Distinguish small and large scratches
    close_zoom_window (WindowHandleZoom, Width, Height)
    select_shape (Errors, Scratches, 'area', 'and', 50, 10000)
    select_shape (Errors, Dots, 'area', 'and', 1, 50)
    dev_display (Image)
    dev_set_color ('red')
    dev_display (Scratches)
    dev_set_color ('blue')
    dev_display (Dots)
    Message := 'Extracted surface scratches'
    Message[1] := 'Not categorized as scratches'
    disp_message (WindowID, Message, 'window', 440, 310, ['red','blue'], 'true')

     

    * This program shows how to detect defects (scratches) in
    * an inhomogeneously illuminated surface by filtering in
    * the frequency domain.
    * First, a suitable bandpass filter is created. Then, the
    * input image is fourier transformed and filtered in the
    * frequency domain, so that high frequency information is
    * enhanced. Finally, it is transformed back to the
    * spatial domain and the enhanced defects are post-processed
    * by morphology.
    * 
    dev_update_off ()
    dev_close_window ()
    read_image (Image, 'surface_scratch')
    invert_image (Image, ImageInverted)
    get_image_size (Image, Width, Height)
    dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
    set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
    dev_display (Image)
    * 
    * Optimize the speed of the fast fourier transform
    * Message := 'Optimize the speed of the fast fourier transform.'
    * Message[1] := 'Please wait...'
    * disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    * optimize_rft_speed (Width, Height, 'standard')
    * disp_continue_message (WindowHandle, 'black', 'true')
    * stop ()
    * 
    * Enhance the scratches by filtering in the frequency domain
    gen_sin_bandpass (ImageBandpass, 0.4, 'none', 'rft', Width, Height)
    rft_generic (ImageInverted, ImageFFT, 'to_freq', 'none', 'complex', Width)
    convol_fft (ImageFFT, ImageBandpass, ImageConvol)
    rft_generic (ImageConvol, Lines, 'from_freq', 'n', 'byte', Width)
    * 
    * Segment the scratches by using morphology
    threshold (Lines, Region, 5, 255)
    connection (Region, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5, 5000)
    dilation_circle (SelectedRegions, RegionDilation, 5.5)
    
    
    
    union1 (RegionDilation, RegionUnion)
    reduce_domain (Image, RegionUnion, ImageReduced)
    lines_gauss (ImageReduced, LinesXLD, 0.8, 3, 5, 'dark', 'false', 'bar-shaped', 'false')
    union_collinear_contours_xld (LinesXLD, UnionContours, 40, 3, 3, 0.2, 'attr_keep')
    select_shape_xld (UnionContours, SelectedXLD, 'contlength', 'and', 15, 1000)
    gen_region_contour_xld (SelectedXLD, RegionXLD, 'filled')
    union1 (RegionXLD, RegionUnion)
    dilation_circle (RegionUnion, RegionScratches, 10.5)
    * 
    * Display the results
    dev_set_draw ('margin')
    dev_set_line_width (3)
    dev_set_colored (12)
    dev_display (Image)
    dev_display (RegionScratches)


    --------------------- 
    作者:机器视觉专业论坛 
    来源:CSDN 
    原文:https://blog.csdn.net/chailiren/article/details/65448932 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • 今天在51Halcon网站答疑区看到划痕检测的求助,觉得挺有意思,就用OpenCV实现了下,这里分享给大家。 问题链接:https://www.51halcon.com/thread-941-1-1.html 1. 检测步骤 先上原图: 这个问题就是检测上图环上...
  • 这里我主要是识别污渍和划痕 缺陷类型 污渍: 划痕: 最后的成果 sum:为工件的总个数 scratch_num:为含有划痕工件的总个数 blot_num:为含有污渍工件的总个数 黄颜色圈住的缺陷为划痕 蓝颜色圈住的缺陷为污渍 ...
  • 对于Python中的一个小实验我正在做我想要找到水果的小划痕.划痕非常小,很难被人眼检测到.我正在使用高分辨率相机进行该实验.这是我想要检测的缺陷:原始图片:这是我的结果,只有很少的代码行:所以我找到了水果的...
  • 今天给大家分享一个OpenCV检测划痕缺陷的小例子,原图如下:上面的图片如果直接用阈值操作并不能很好的分割划痕与背景,尝试如下:本文的实现思路步骤:① 原图均值滤波② 滤波图像与原图进行差分③ 二值化④ 查找...
  • opencv数字识别

    2019-03-15 13:27:29
    针对opencv入门的同学,本程序使用模板匹配的方法,实现了图片中数字的自动识别,包括有划痕和有噪点的图片识别。
  • opencv 数字识别详细教程

    万次阅读 多人点赞 2016-01-10 16:11:28
    最近要做数字识别这块,但是自己又完全不懂这个,网上搜资料搜了好多,...我是在VS2013 和opencv 2.4.9 环境下实现的。关于环境的搭建和配置以及软件的下载可以可以参考,http://blog.csdn.net/ltg01/article/detail
  • OpenCV 傅里叶变换

    2020-03-01 22:52:51
    介绍了opencv实现傅里叶变换的方法。
  • OpenCV 数字验证码识别

    万次阅读 2015-07-17 21:46:34
    主要完成的功能就是自动识别图片中的数字,图片包括正常图片,有划痕图像和有噪点图像。分别如下先上图,看识别效果!接下来开始来点干货了: opencv的安装与配置:这个要是展开讲可以再写一篇博文了,我当时什么都...
  • 使用Opencv完成图像修复什么是图像修复Opencv图像修复算法基于Navier-Stokes的修复算法基于Fast Marching的修复算法赞成者和反对者代码     想象一下这样的场景,你从你的老家找到一张相片,并...
  • OpenCV 图像处理编程学习笔记

    千次阅读 2018-07-28 11:09:47
    OpenCV编程实例代码》各章重点知识点简述 第一章 OpenCv环境配置 主要讲解了 OpenCV 的各种开发环境的配置,其中以Sublime 作为主要的配置环境的介绍,这里我们主要使用 VScode 进行开发。 第二章 ...
  • opencv常用函数

    2019-08-30 19:08:50
    用于读取文件中的图片到OpenCV中 imshow 在指定的窗口中显示一幅图像 namedWindow 用于创建一个窗口 imwrite 输出图像到文件 createTrackbar 用于创建一个可以调整数值的轨迹条 getTrackbarPos 用于获取...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 230
精华内容 92
关键字:

opencv去划痕