计算机视觉驱动的鸭蛋双黄与裂纹与新鲜度无损检测【附代码】
✨ 长期致力于鸭蛋、计算机视觉、无损检测、双黄、裂纹、新鲜度研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
✅如需沟通交流,点击《获取方式》
(1)基于卷积神经网络的双黄鸭蛋动态在线检测系统:
构建了包含透射光源和工业相机的图像采集装置,光源采用12V/20W LED阵列,色温6500K,相机分辨率为1280×960像素,帧率30fps。双黄鸭蛋的透射图像中蛋黄阴影呈现两个分离或重叠的暗区。设计了一个轻量化卷积神经网络DoubleYolkNet,结构包括三个卷积层(卷积核大小5×5、步长2,输出通道分别为16、32、64)、两个最大池化层(2×2)和两个全连接层(输出128和2)。激活函数采用ReLU,输出层使用Softmax。在训练过程中,收集了单黄鸭蛋图像5000张,双黄鸭蛋图像2000张,采用数据增强(旋转±15度,缩放0.8-1.2倍,亮度调整±20%)。训练采用Adam优化器,学习率0.001,批次大小32,迭代50轮。验证准确率达到单黄97.5%,双黄98%。将训练好的模型部署到在线检测系统中,使用C#编写上位机,通过Matlab编译的dll调用CNN推理。输送线速度设定为1枚蛋/秒,光电触发拍照后100ms内完成图像处理和判别,总体检测速度达标。在实际生产中连续测试2000枚鸭蛋(其中双黄蛋60枚),系统正确识别单黄蛋1830枚(误判20枚),双黄蛋55枚(漏检5枚),准确率单黄94%,双黄91.7%。系统对蛋壳颜色(青壳、白壳)和鸭蛋大小(50-70g)不敏感,鲁棒性好。
(2)亮裂纹与暗裂纹的自适应增强分割算法:
针对透射光下鸭蛋裂纹的灰度差异小的问题,设计了自适应光源亮度调节策略。通过调节LED供电电压从5V到12V,采集不同亮度下的蛋壳图像,选取裂纹对比度最大的电压值(亮裂纹采用8V,暗裂纹采用11V)。亮裂纹增强使用线性反锐化掩模,将原图与高斯模糊(sigma=1.5)的差值乘以系数2.5后叠加回原图。然后采用区域生长法分割,种子点选择灰度局部最小值(亮裂纹为暗线),生长准则为相邻像素灰度差小于15。连通区域面积大于20像素且长宽比大于5的被判为裂纹。暗裂纹采用Retinex理论增强,将图像分解为光照分量和反射分量,反射分量作为增强结果。区域生长时阈值设为相邻像素差小于8,连通面积大于15像素。对200张亮裂纹图像(裂纹宽度>0.1mm)测试,亮裂纹检测准确率95%;对150张暗裂纹图像(宽度0.03-0.08mm)测试,暗裂纹检测准确率81.3%,完好蛋误判率3.7%。综合判别算法将亮裂纹和暗裂纹统一输出,对裂纹鸭蛋总体准确率88.3%。
(3)激光气室成像与新鲜度等级判别:
设计了一种以650nm红色激光二极管(功率5mW)为光源的图像采集装置,激光束以45度角照射鸭蛋钝端,在蛋壳内部反射后气室区域形成清晰的环形光斑。相机在正上方采集反射图像,激光光斑的半径与气室面积成正比。通过图像处理后,计算气室面积与鸭蛋投影面积的比值R。新鲜度等级按哈夫单位划分:AA级(R<0.08),A级(0.08≤R<0.15),B级(R≥0.15)。在实验室环境下测试300枚鸭蛋(室温25度,贮藏时间1-20天),激光法测得的R值与实际气室直径(破坏性测量)的相关系数为0.94。建立的判别模型对三个等级的准确率分别为89.5%、84.9%和97.5%。其中A级误判较多,主要是因为气室面积边界模糊导致图像分割误差。将激光功率提高至10mW并增加偏振滤光片后,对比度提升12%,A级准确率提高到87.6%。该方法的检测速度可达2枚/秒,无需接触,适合生产线在线新鲜度分选。
import cv2 import numpy as np import tensorflow as tf def build_double_yolk_net(input_shape=(128,128,1)): model = tf.keras.Sequential([ tf.keras.layers.Conv2D(16, 5, strides=2, activation='relu', input_shape=input_shape), tf.keras.layers.MaxPooling2D(2), tf.keras.layers.Conv2D(32, 5, strides=2, activation='relu'), tf.keras.layers.MaxPooling2D(2), tf.keras.layers.Conv2D(64, 5, strides=2, activation='relu'), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(2, activation='softmax') ]) return model def crack_enhancement_retinex(image, sigma=30): # 单尺度Retinex增强暗裂纹 blur = cv2.GaussianBlur(image, (0,0), sigma) reflectance = np.log1p(image.astype(np.float32)) - np.log1p(blur.astype(np.float32)) reflectance = (reflectance - reflectance.min()) / (reflectance.max() - reflectance.min()) * 255 return reflectance.astype(np.uint8) def region_growing_crack(gray_img, seed_threshold=15, grow_threshold=8): # 区域生长算法提取裂纹 h,w = gray_img.shape visited = np.zeros_like(gray_img, dtype=bool) # 选择种子点:局部极小值且灰度小于均值-阈值 mean_val = np.mean(gray_img) seeds = [] for i in range(1, h-1): for j in range(1, w-1): if gray_img[i,j] < mean_val - seed_threshold and gray_img[i,j] < gray_img[i-1,j] and gray_img[i,j] < gray_img[i+1,j]: seeds.append((i,j)) regions = [] for seed in seeds: if visited[seed]: continue stack = [seed] region = [] while stack: x,y = stack.pop() if visited[x,y]: continue visited[x,y] = True region.append((x,y)) for dx in [-1,0,1]: for dy in [-1,0,1]: nx, ny = x+dx, y+dy if 0<=nx<h and 0<=ny<w and not visited[nx,ny]: if abs(int(gray_img[nx,ny]) - int(gray_img[x,y])) < grow_threshold: stack.append((nx,ny)) if len(region) > 20: regions.append(region) return regions def air_cell_ratio(image, laser_spot_center): # 激光气室图像分割计算面积比 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY) contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 找到激光光斑轮廓(最大轮廓) laser_contour = max(contours, key=cv2.contourArea) laser_area = cv2.contourArea(laser_contour) # 鸭蛋投影面积(先找蛋轮廓) egg_contour = max(contours, key=cv2.contourArea) # 简化 egg_area = cv2.contourArea(egg_contour) ratio = laser_area / egg_area if ratio < 0.08: grade = 'AA' elif ratio < 0.15: grade = 'A' else: grade = 'B' return ratio, grade ",