复习opencv:螺丝螺纹缺陷检测

螺牙缺陷检测

  • 简述
  • 去噪
    • 椒盐噪声
    • 高斯噪声
  • 小波变换
  • 引导滤波
  • 求最大凸包
  • 判断曲直
  • 全部代码

简述

  • 今天收到了一个检测螺牙缺陷的问题,当复习opencv练个手,记录一下基础知识。
  • 这里的代码是检测弯曲的,其他缺陷用yolo处理。
  • 东家给的图片有的是有干扰的(红框标识),所以要求一下最大凸包。
    在这里插入图片描述
  • 里面很多知识是复习用,最终代码在最后一行,给的101张图片,有2个弯曲度超过0.25,来到了0.33以上
  • 有个小技巧可以提高弯直的区分度,这里就不介绍了,需要的私信。

去噪

椒盐噪声

import cv2img = cv2.imread('image.jpg')
median = cv2.medianBlur(img, 5)
cv2.imshow('Median filter', median)
cv2.waitKey(0)
cv2.destroyAllWindows()

高斯噪声

import cv2img = cv2.imread('image.jpg')
gaussian = cv2.GaussianBlur(img, (5,5), 0)
cv2.imshow('Gaussian filter', gaussian)
cv2.waitKey(0)
cv2.destroyAllWindows()

小波变换

import cv2
import pywtimg = cv2.imread('image.jpg', 0)
coeffs = pywt.dwt2(img, 'haar')
cA, (cH, cV, cD) = coeffs
cv2.imshow('Wavelet denoising', pywt.idwt2((cA, (None, None, None)), 'haar'))
cv2.waitKey(0)
cv2.destroyAllWindows()

引导滤波

import numpy as np
import cv2main_path="D:/Handletiling/NG_org_20230602103406819.bmp"def guideFilter(I, p, winSize, eps):mean_I = cv2.blur(I, winSize)    mean_p = cv2.blur(p, winSize)       mean_II = cv2.blur(I * I, winSize)  mean_Ip = cv2.blur(I * p, winSize) var_I = mean_II - mean_I * mean_I  cov_Ip = mean_Ip - mean_I * mean_p  a = cov_Ip / (var_I + eps)        b = mean_p - a * mean_I          mean_a = cv2.blur(a, winSize)     mean_b = cv2.blur(b, winSize)     q = mean_a * I + mean_breturn qif __name__ == '__main__':eps = 0.01winSize = (5,5)image = cv2.imread(main_path, cv2.IMREAD_ANYCOLOR)image = cv2.resize(image, None,fx=0.7, fy=0.7, interpolation=cv2.INTER_CUBIC)I = image/255.0        #将图像归一化p =IguideFilter_img = guideFilter(I, p, winSize, eps)# 保存导向滤波结果guideFilter_img  = guideFilter_img  * 255guideFilter_img [guideFilter_img  > 255] = 255guideFilter_img  = np.round(guideFilter_img )guideFilter_img  = guideFilter_img.astype(np.uint8)cv2.imshow("image",image)cv2.imshow("winSize_5", guideFilter_img )cv2.waitKey(0)cv2.destroyAllWindows()

求最大凸包

import cv2
import os
import numpy as np
from skimage.measure import labelmain_path="D:\Handletiling\luoya/NG/NG_org_20230602103407364.bmp"##method1 --opencv
def get_lagrest_connect_component1(img):# rgb->grayimg_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# gaussian filterimg_gray = cv2.GaussianBlur(img_gray, (5, 5), 0)# binary exp-threshold=0_, img_gray = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV)  # ret==threshold# find contourcontours, _ = cv2.findContours(img_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# cv2.drawContours(img_gray, contours, -1, 255, 3)# find the area_max regionarea = []for i in range(len(contours)):area.append(cv2.contourArea(contours[i]))if len(area) >= 1:max_idx = np.argmax(area)max_contour_area = area[max_idx]for k in range(len(contours)):if k != max_idx:cv2.fillPoly(img_gray, [contours[k]], 0)else:max_contour_area = 0return max_contour_area, img_grayif __name__ == '__main__':img = cv2.imread(main_path)max_area, img_gray = get_lagrest_connect_component1(img)print(max_area)cv2.imwrite('img_gray.jpg', img_gray)

判断曲直

1.查找轮廓,提取凸包
2.获得点集
3.计算导数方差
4.比较阈值

def calccurl(str,thresh):img = cv2.imread(str)# cv2.imshow('src',img)#提取凸包max_area, img_gray =get_lagrest_connect_component1(img)gray = img_gray#阈值处理ret,binary = cv2.threshold(gray,127,255,0)#查找轮廓,提取凸包contours,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)hull = cv2.convexHull(contours[0])cv2.polylines(img_gray,[hull],True,(255,255,0),2)min_x=min(hull[:,0,0])max_x=max(hull[:,0,0])topList=[]bottomList=[]thresh_left=220thresh_right=30count=hull.shape[0]isthesame=Falsefor i in range(hull.shape[0]):point = tuple(hull[i][0]) #  # cv2.circle(img, point, 1, (0, 255, 0) , 12)if point[0]<(max_x-thresh_right) and point[0]>(min_x+thresh_left):length=binary.shape[0]x1 = np.linspace(start=0, stop=length-1, num=length)temp=x1 * (binary[:, point[0]] / 255)n = np.sum(temp > 0)index=temp.sum()/(n*1.)# if i in[0,count-1]:#     if not isthesame:#         isthesame=True#     else:#         continueif point[1]>index:bottomList.append(point)# cv2.putText(img, str(i), point, cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)# print(str(i) + ":", point)else:topList.append(point)# cv2.putText(img, str(i), point, cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)# print(str(i) + ":", point)space = np.linspace(start=min_x+thresh_left, stop=max_x-thresh_right, num=15)space= np.ceil(space)length = img_gray.shape[0]x1 = np.linspace(start=0, stop=length - 1, num=length)tempM = (img_gray / 255.)* x1[:,None]if len(topList) >len(bottomList):topList.clear()for x in space:temp=tempM[:, int(x)]temp = temp[temp != 0]topList.append([x,temp.min()])# cv2.circle(img, (int(x),int(temp.min())), 1, (0, 255, 0), 12)# cv2.putText(img, str(x), (int(x),int(temp.min())), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)line = np.array(topList, dtype=float)else:bottomList.clear()for x in space:temp = tempM[:, int(x)]temp = temp[temp != 0]bottomList.append([x, temp.max()])# cv2.circle(img, (int(x), int(temp.max())), 1, (0, 255, 0), 12)# cv2.putText(img, str(x), (int(x),int(temp.max())), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)line = np.array(bottomList, dtype=float)if line.size > 0:#method1slopend=(line[-1,1]-line[0,1])/(line[-1,0]-line[0,0])slop=(line[1:,1]-line[:-1,1])/((line[1:,0]-line[:-1,0])+0.0001)dis=slop-slopendstd = np.std(dis)if std>thresh:return 0,stdreturn 1,0# method2# std= np.std(slop)if __name__ == '__main__':filesPath = os.listdir(main_path)threshstd=0.025files = tqdm(filesPath)for file in files:absolute_file_path = os.path.join(main_path, file)if '.bmp' in absolute_file_path.lower():result,std=calccurl(absolute_file_path,threshstd)if result:print(absolute_file_path+":", std)

在这里插入图片描述

结果
--------------------
std: 0.037498851806574245

全部代码

import cv2
import numpy as npimport os
from tqdm import tqdm
import shutil#需要检测弯曲的图片的文件夹地址
main_path="D:\Handletiling\src"def get_lagrest_connect_component1(img):img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)img_gray = cv2.GaussianBlur(img_gray, (5, 5), 0)_, img_gray = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV)  # ret==thresholdcontours, _ = cv2.findContours(img_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)area = []for i in range(len(contours)):area.append(cv2.contourArea(contours[i]))if len(area) >= 1:max_idx = np.argmax(area)max_contour_area = area[max_idx]for k in range(len(contours)):if k != max_idx:cv2.fillPoly(img_gray, [contours[k]], 0)else:max_contour_area = 0return max_contour_area, img_graydef calccurl(str,thresh):img = cv2.imread(str)#提取凸包max_area, img_gray =get_lagrest_connect_component1(img)gray = img_gray#阈值处理ret,binary = cv2.threshold(gray,127,255,0)#查找轮廓contours,hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)hull = cv2.convexHull(contours[0])cv2.polylines(img_gray,[hull],True,(255,255,0),2)min_x=min(hull[:,0,0])max_x=max(hull[:,0,0])topList=[]bottomList=[]thresh_left=220thresh_right=30count=hull.shape[0]isthesame=Falsefor i in range(hull.shape[0]):point = tuple(hull[i][0]) ## cv2.circle(img, point, 1, (0, 255, 0) , 12)if point[0]<(max_x-thresh_right) and point[0]>(min_x+thresh_left):length=binary.shape[0]x1 = np.linspace(start=0, stop=length-1, num=length)temp=x1 * (binary[:, point[0]] / 255)n = np.sum(temp > 0)index=temp.sum()/(n*1.)# if i in[0,count-1]:#     if not isthesame:#         isthesame=True#     else:#         continueif point[1]>index:bottomList.append(point)# cv2.putText(img, str(i), point, cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)# print(str(i) + ":", point)else:topList.append(point)# cv2.putText(img, str(i), point, cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)# print(str(i) + ":", point)space = np.linspace(start=min_x+thresh_left, stop=max_x-thresh_right, num=15)space= np.ceil(space)length = img_gray.shape[0]x1 = np.linspace(start=0, stop=length - 1, num=length)tempM = (img_gray / 255.)* x1[:,None]if len(topList) >len(bottomList):topList.clear()for x in space:temp=tempM[:, int(x)]temp = temp[temp != 0]topList.append([x,temp.min()])# cv2.circle(img, (int(x),int(temp.min())), 1, (0, 255, 0), 12)# cv2.putText(img, str(x), (int(x),int(temp.min())), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)line = np.array(topList, dtype=float)else:bottomList.clear()for x in space:temp = tempM[:, int(x)]temp = temp[temp != 0]bottomList.append([x, temp.max()])# cv2.circle(img, (int(x), int(temp.max())), 1, (0, 255, 0), 12)# cv2.putText(img, str(x), (int(x),int(temp.max())), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 3)line = np.array(bottomList, dtype=float)if line.size > 0:#method1slopend=(line[-1,1]-line[0,1])/(line[-1,0]-line[0,0])slop=(line[1:,1]-line[:-1,1])/((line[1:,0]-line[:-1,0])+0.0001)dis=slop-slopendstd = np.std(dis)if std>thresh:return 0,stdreturn 1,0# method2# std= np.std(slop)if __name__ == '__main__':filesPath = os.listdir(main_path)threshstd=0.025files = tqdm(filesPath)for file in files:absolute_file_path = os.path.join(main_path, file)if '.bmp' in absolute_file_path.lower():result,std=calccurl(absolute_file_path,threshstd)if not result:print(absolute_file_path+"-图片弯曲:", std)
#结果
[00:00<00:01, 44.18it/s]D:\Handletiling\src\NG_org_20230602103409544.bmp-图片弯曲: 0.0334415572613885
[00:00<00:01, 44.24it/s]D:\Handletiling\src\NG_org_20230602103410530.bmp-图片弯曲: 0.037498851806574245

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/21229.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

能翻译维吾尔语的软件有哪些?这几个可以用用看

能翻译维吾尔语的软件有哪些&#xff1f;在如今全球化的背景下&#xff0c;不同语言之间的沟通交流变得尤为重要。维吾尔语作为中国特有的少数民族语言之一&#xff0c;它的翻译需求日益增长。本文将介绍几款精选的维吾尔语翻译软件&#xff0c;帮助大家顺利实现跨语言沟通。 智…

驱动 day10 作业

要求&#xff1a;platform驱动实现 现象&#xff1a; test.c应用程序 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #in…

Linux系统编程(信号处理 sigacation函数和sigqueue函数 )

文章目录 前言一、sigaction二、sigqueue函数三、代码示例总结 前言 本篇文章我们来介绍一下sigacation函数和sigqueue函数。 一、sigaction sigaction 是一个用于设置和检查信号处理程序的函数。它允许我们指定信号的处理方式&#xff0c;包括指定一个函数作为信号处理程序…

XML文档详解

目录 XML文档 一、XML文件 二、Dom4J解析XML文件 三、Sax解析XML文件 四、使用Dom4j的XPath解析XML文件 4.1XPath语法 4.2 获取sys-config.xml文件的配置信息 4.3 获取server.xml文件的配置信息 4.4 获取bookstore.xml文件的配置信息 XML文档 一、XML文件 1.1 学习重…

MySQL 主从延迟的常见原因及解决方法

主从延迟作为 MySQL 的痛点已经存在很多年了&#xff0c;以至于大家都有一种错觉&#xff1a;有 MySQL 复制的地方就有主从延迟。 对于主从延迟的原因&#xff0c;很多人将之归结为从库的单线程重放。 但实际上&#xff0c;这个说法比较片面&#xff0c;因为很多场景&#xf…

1765_Perl实现fileread功能

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) fileread是MATLAB中的一个函数&#xff0c;可以实现对一个文本文件的全文读取。读取后的内容返回给一个字符串量。在Python中也有类似的功能&#xff0c;不过MATLAB中的这个更能…

python简单使用【mac-ide:pycharm】

小白实用快捷键记录 一、Mac下安装并配置python3开发环境二、python学习三、pycharm常用快捷键记录 一、Mac下安装并配置python3开发环境 点我查看python及pycharm下载安装、环境配置 二、python学习 不是很推荐&#xff0c;想系统学习的同学可以做个参考&#xff1a; Pytho…

2023年7月13日,Stream流,Stream流的获取,Stream流中间聚合操作,Stream流终结操作,Calendar时间日期类,包装类

Stream流 1. 单列集合的Stream流获取 Java中的Stream流操作可以分为中间操作和终止操作两种。 中间操作包括&#xff1a; filter&#xff1a;对流中的元素进行筛选。map&#xff1a;对流中的元素进行转换。flatMap&#xff1a;对流中的元素进行扁平化映射。distinct&#x…

数据库模型设计案例分享(GaussDB版)

目录 一、前言 二、应用系统数据库设计的基本流程 三、数据库模型设计 1、概念结构设计阶段 2、逻辑结构设计阶段 3、物理结构设计阶段 四、小结 一、前言 GaussDB数据库是一款企业级分布式数据库&#xff0c;支持集中式和分布式两种部署形态。它面向金融互联网交易和政…

单例模式:懒汉式和饿汉式

目录 懒汉模式和饿汉模式 区别 示例 懒汉模式线程不安全 懒汉模式线程安全 懒汉模式内部静态变量线程安全 饿汉式线程安全 指的是在系统生命周期内&#xff0c;只产生一个实例。 懒汉模式和饿汉模式 分为懒汉式和饿汉式 区别 创建时机和线程安全 线程安全&#xff1…

【bash:xxx:command not found问题,在英伟达nvidia的jetson-orin-nx上遇到的>>>解决方式之一】

【bash:xxx:command not found问题,在英伟达nvidia的jetson-orin-nx上遇到的>>>解决方式之一】 1、概述2、实验环境3、问题描述&#xff1a;bash:xxx:command not found问题4、我的努力第一种方式&#xff1a;加入指令方式第二种方式&#xff1a;使用echo $PATH命令查…

【Docker】docker基础使用

文章目录 docker概念什么是dockerdocker引擎迭代docker与虚拟机docker版本发展 docker基础docker架构docker Registry(镜像仓库)镜像仓库使用流程实际研发镜像仓库使用不同镜像仓库的拉取 docker常用命令镜像仓库命令docker logindocker pulldocker pushdocker searchdocker lo…