扫描以上标准模板滑动采集图像及其处理

网友投稿 624 2022-05-28

简 介:

对于喷涂有黄色油漆的金属圆盘进行扫描。利用 滑轨带动圆盘 在 V370扫描仪 上移动,利用300dpi分辨率获得金属圆盘模板在扫描仪上不同位置和高度的图片,通过后期算法研究扫描仪在不同地方的失真以及影响测量准确性的因素。

关键词:

V370,扫描仪,cv2,HoughCircles

扫描图片

目 录

Contents

喷涂黄色油

漆的阴影圈

移动距离

扫描结果

处理图片

检测圆形

检测精度问题

加速处理

图片预分割

Studio带有GPU环境

处理总结

扫描图片

目 录

Contents

喷涂黄色油

漆的阴影圈

移动距离

扫描结果

扫描以上的标准模板滑动采集图像及其处理

处理图片

检测圆形

检测精度问题

加速处理

图片预分割

Studio带有GPU环境

处理总结

1.1 喷涂黄色油漆的阴影圈

在 获取棋盘格与标准模板在扫描仪上不同位置图片 使用金属阴影圈模板在V370扫描以上进行取像的时候,由于金属表面的反射使得对应的模板图像出现亮度变化过大,会影响到后期模板圆孔面积的求取,进而使得对扫描仪的扫描精度测试产生影响。

1.2 移动距离

根据 获取棋盘格与标准模板在扫描仪上不同位置图片 测量蜗杆滑轨的运动系数:

扫描以上的金属模板移动距离:130cm。根据上面测量到的蜗杆滑轨运动系数,可以知道扫描范围的步数为: 130 × 202.53 = 2646 130 \times 202.53 = 2646 130×202.53=2646 。实际工作中定位2600。

1.2.1 扫描程序

from headm import * from tsmodule.tshardware import * ''' rcccw(2000) exit() ''' epson_title = 'EPSON' save_title = '文件保存设置' process_title = '进程' def epsonScan(): tspsendwindowkey(epson_title, "s", alt=1,noreturn=1) time.sleep(.1) if sum(tspgetwindowrect(save_title)) != 0: tspsendwindowkey(save_title, "\r", noreturn=1) while True: time.sleep(1) if(sum(tspgetwindowrect(process_title)) != 0): break tspbeep(800, 20) while True: time.sleep(1) if(sum(tspgetwindowrect(process_title)) == 0): break tspbeep(1800, 20) printf('\a') for i in range(50): printf("Scan time:%d"%i) epsonScan() rcccw(52) printf('\a')

1.3 扫描结果

1.3.1 水平移动扫描

1.3.2 对角线移动扫描

通过基于ESP8266 WiFi控制的步进升降机械平台移动固定步数,测量移动距离。

因此,每移动1mm,驱动器需要驱动50个脉冲。

驱动模块沿着对角线移动可以同时测量到扫描仪在上下以及左右方向中引起图像尺寸变化的情况。

1.3.3 上下移动扫描

使用 基于WiFi步进电机驱动单蜗杆滑轨带动阴影圈圆盘 在扫描仪上网上移动。

2.1 检测圆形

2.1.1 利用HoughCircles检测

def modelArg(filename): img = cv2.imread(os.path.join(filedir,filename)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 50, param1=220, param2=30, minRadius=90, maxRadius=115) return img, circles

由于所检测到的四个圆圈在输出结果上并没有进行排序,因此通过下面程序对于四个结果进行排序。

def sortcircles(cc): cca = mean(cc[0], axis=0) angle = [math.atan2(c[1]-cca[1], c[0]-cca[0])*180/pi for c in cc[0]] angle = [s if s >= 0 else 360+s for s in angle] ar = sorted(zip(angle, cc[0].T[2])) sortr = [s[1] for s in ar] rcompare = list(array(sortr) > 100) for i in range(3): rc = roll(rcompare, i+1) rsr = roll(sortr, i+1) if rc[0] == True and rc[1] == True: break return rsr

2.1.2 检测结果

std(r1dim): 0.6596184372901917 std(r2dim): 0.5734277367591858 std(r3dim): 0.6673048138618469 std(r4dim): 0.5788406133651733 max(r1dim)-min(r1dim): 3.3000030517578125 max(r2dim)-min(r2dim): 2.5 max(r3dim)-min(r3dim): 3.6999969482421875 max(r4dim)-min(r4dim): 3.0

#!/usr/local/bin/python # -*- coding: gbk -*- #============================================================ # PROC1.PY -- by Dr. ZhuoQing 2022-01-25 # # Note: #============================================================ from headm import * # = import cv2 from tqdm import tqdm from tqdm import tqdm scandiag = '/home/aistudio/work/Scanner/ScanDiag' scanrow = '/home/aistudio/work/Scanner/ScanRow' scanvert = '/home/aistudio/work/Scanner/ScanVert' filedir = scanrow filedim = sorted([s for s in os.listdir(filedir) if s.find('jpg') > 0]) #printt(filedim:) #------------------------------------------------------------ ''' gifpath = '/home/aistudio/GIF' if not os.path.isdir(gifpath): os.makedirs(gifpath) gifdim = os.listdir(gifpath) for f in gifdim: fn = os.path.join(gifpath, f) if os.path.isfile(fn): os.remove(fn) for id,f in tqdm(enumerate(filedim)): fn = os.path.join(filedir, f) img = cv2.imread(fn)[:,:,::-1] img[where(img < 50)] = 0 plt.clf() plt.figure(figsize=(8,12)) plt.imshow(img) savefile = os.path.join(gifpath, '%03d.jpg'%id) plt.savefig(savefile) ''' #------------------------------------------------------------ def modelArg(filename): img = cv2.imread(os.path.join(filedir,filename)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 50, param1=150, param2=40, minRadius=90, maxRadius=115) # circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, # 50, param1=220, param2=30, # minRadius=170, maxRadius=240) return img, circles #------------------------------------------------------------ def circleImg(img, cc): for c in cc[0]: cv2.circle(img, (int(c[0]), int(c[1])), int(c[-1]), (0,0,255), 12) return img #------------------------------------------------------------ def sortcircles(cc): # printt(cc[0]) cca = mean(cc[0], axis=0) angle = [math.atan2(c[1]-cca[1], c[0]-cca[0])*180/pi for c in cc[0]] angle = [s if s >= 0 else 360+s for s in angle] ar = sorted(zip(angle, cc[0].T[2])) sortr = [s[1] for s in ar] rcompare = list(array(sortr) > 100) for i in range(3): rc = roll(rcompare, i+1) rsr = roll(sortr, i+1) if rc[0] == True and rc[1] == True: break return rsr #------------------------------------------------------------ gifpath = '/home/aistudio/GIF' if not os.path.isdir(gifpath): os.makedirs(gifpath) gifdim = os.listdir(gifpath) for f in gifdim: fn = os.path.join(gifpath, f) if os.path.isfile(fn): os.remove(fn) allcircle = [] for id,f in tqdm(enumerate(filedim)): f = filedim[2] img, cc = modelArg(f) printt(cc:) if len(cc) > 0: img[where(img<50)] = 0 circleImg(img, cc) r = sortcircles(cc) allcircle.append(r) plt.clf() plt.figure(figsize=(8,12)) plt.imshow(img[:,:,::-1]) savefile = os.path.join(gifpath, '%03d.jpg'%id) plt.savefig(savefile) break #------------------------------------------------------------ #printt(allcircle) ''' r1dim = [c[0] for c in allcircle] r2dim = [c[1] for c in allcircle] r3dim = [c[2] for c in allcircle] r4dim = [c[3] for c in allcircle] plt.clf() plt.figure(figsize=(12,8)) plt.plot(r1dim, label='Circle1') plt.plot(r2dim, label='Circle2') plt.plot(r3dim, label='Circle3') plt.plot(r4dim, label='Circle4') plt.xlabel("n") plt.ylabel("Ratio") plt.grid(True) plt.legend(loc='upper right') plt.tight_layout() plt.savefig('/home/aistudio/stdout.jpg') plt.show() printt(std(r1dim):,std(r2dim):,std(r3dim):,std(r4dim):) printt(max(r1dim)-min(r1dim):, max(r2dim)-min(r2dim):, max(r3dim)-min(r3dim):, max(r4dim)-min(r4dim):) ''' #------------------------------------------------------------ # END OF FILE : PROC1.PY #============================================================

2.2 检测精度问题

在前面处理图片过程中,由于使用了Hough算法,它在检测圆形参数的时候,精度不是很高。这是Hough算法本身的精度问题。因此需要在初步获得圆形位置的基础上,进一步提高圆形半径的检测精度。

2.2.1 采用ContourArea函数

根据前面讨论过程,为了进一步提高圆半径检测精度,可以采用OpenCV中的Contour以及ContourArea的算法,通过对图片进行分割之后,提取黑色区域的面积从而反过来计算影响半径。

2.2.2 对于边缘过渡带进行拟合

圆形的半径来自于边缘过渡带的细分,对于过渡带的灰度变化进行建模,使用上升沿的中点进行拟合来获取亚像素级别的半径。

了提高图片的处理速度,为后面提高高性能算法,需要对图片进行预处理。

3.1 图片预分割

在测量的图片中,圆形模板仅仅占图片的一小部分,利用前面提取的模板中圆形的中心位置,将涵盖后模板的图片区域分割出来,这一方面减少了图片数据存储的空间,并未后面进行搜索和处理提高了处理速度。

3.1.1 处理程序

from headm import * # = from tqdm import tqdm import cv2 scandiag = '/home/aistudio/work/Scanner/ScanDiag' scanrow = '/home/aistudio/work/Scanner/ScanRow' scanvert = '/home/aistudio/work/Scanner/ScanVert' scandiagblock = '/home/aistudio/work/Scanner/ScanDiagBlock' scanrowblock = '/home/aistudio/work/Scanner/ScanRowBlock' scanvertblock = '/home/aistudio/work/Scanner/ScanVertBlock' filedir = scandiag outfiledir = scandiagblock filedim = sorted([s for s in os.listdir(filedir) if s.find("jpg") > 0]) def modelArg(filename): img = cv2.imread(os.path.join(filedir,filename)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) bigcircle = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 50, param1=200, param2=60, minRadius=530, maxRadius=580) return img, bigcircle, bigcircle BLOCK_SIDE2 = 600 for id,f in tqdm(enumerate(filedim)): if id >= 0: img,c,bc = modelArg(f) cc = bc[0][0] keepcc = cc leftid = int(cc[0] - BLOCK_SIDE2) topid = int(cc[1] - BLOCK_SIDE2) if leftid < 0: leftid = 0 if topid < 0: topid = 0 rightid = leftid + BLOCK_SIDE2*2 bottomid = topid + BLOCK_SIDE2*2 if rightid > img.shape[1]: rightid = img.shape[1] leftid = rightid - BLOCK_SIDE2*2 if bottomid > img.shape[0]: bottomid = img.shape[0] topid = bottomid - BLOCK_SIDE2*2 blockimg = img[topid:bottomid, leftid:rightid, :] outfile = os.path.join(outfiledir, f) cv2.imwrite(outfile, blockimg)

3.1.2 处理结果

根据分析图片中金属图片的像素尺寸,可以看到,通过截取大圆半径5/4倍的外接正方形,将原始图像分离出来进行存储。

外轮廓的直径为1105,它的5/4对应的1381。如果截取靠近边缘,则以边缘为起始点往内延长1381,使得所有截取的存储图片的大小都是1381。

from headm import * # = from tqdm import tqdm import cv2 scandiag = '/home/aistudio/work/Scanner/ScanDiag' scanrow = '/home/aistudio/work/Scanner/ScanRow' scanvert = '/home/aistudio/work/Scanner/ScanVert' scandiagblock = '/home/aistudio/work/Scanner/ScanDiagBlock' scanrowblock = '/home/aistudio/work/Scanner/ScanRowBlock' scanvertblock = '/home/aistudio/work/Scanner/ScanVertBlock' filedir = scandiagblock outfiledir = scanrowblock filedim = sorted([s for s in os.listdir(filedir) if s.find("jpg") > 0]) gifpath = '/home/aistudio/GIF' if not os.path.isdir(gifpath): os.makedirs(gifpath) gifdim = os.listdir(gifpath) for f in gifdim: fn = os.path.join(gifpath, f) if os.path.isfile(fn): os.remove(fn) for id,f in tqdm(enumerate(filedim)): img = cv2.imread(os.path.join(filedir, f)) img[where(img<50)] = 0 plt.clf() plt.figure(figsize=(10,10)) plt.imshow(img[:,:,::-1]) savefile = os.path.join(gifpath, '%03d.jpg'%id) plt.savefig(savefile) plt.close()

3.2 Studio带有GPU环境

根据 AI Studio中的OpenCV在三种环境下对比 对比,在存在有GPU处理环境下,也就是在“至尊版本”中,可以获得大约五倍速度的提升。因此对于大量数据处理的时候转移到GPU环境下可以获得更快的速度。

于喷涂有黄色油漆的金属圆盘进行扫描。利用 滑轨带动圆盘 在 V370扫描仪 上移动,利用300dpi分辨率获得金属圆盘模板在扫描仪上不同位置和高度的图片,通过后期算法研究扫描仪在不同地方的失真以及影响测量准确性的因素。

■ 相关文献链接:

获取棋盘格与标准模板在扫描仪上不同位置图片

蜗杆滑轨

基于ESP8266 WiFi控制的步进升降机械平台

实验室中的第三只手:滑轨参数以及控制接口

AI Studio中的OpenCV在三种环境下对比

Epson Perfection V370 Photo图片扫描自动控制

● 相关图表链接:

图1.1.1 喷涂有黄色油漆的阴影圈金属模板

图1.3.1 扫描以上的金属模板移动距离

图1.2.2 扫描结果

图2.1 对角线方向移动

图2.1.1 对角线移动扫描

图3.1 上下扫描结果

图2.1.1 在AI Studio上处理图片

图2.1.2 四个结果对应 圆圈的位置

图2.1.3 检测结果显示

图2.1.4 对角线移动测量

图2.1.5 四个圆圈测量结果

图3.1.1 对角线移动扫描结果

图3.1.2 水平移动

图3.1.3 对角线移动

图3.1.4 垂直移动

AI 图像处理

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:第十章: C语言文件编程(上)
下一篇:kudu参数优化设置,让集群飞起来~
相关文章