想法起源于控制3d打印机初始线径,能够监控平台首层高度是否合理。经过实际测量,不同的高度,精度需求为0.01mm,即程序应该能够区分之分辨率。
```python
%load_ext autoreload
%autoreload 2
import cv2
import os
import numpy as np
from utils import objectFound
```
```python
imgs = [os.path.join("../images/",x) for x in os.listdir("../images/") if x.find("re")>-1]
imgs
```
['../images/1re.jpg', '../images/2re.jpg', '../images/3re.jpg']
## 测量精度
* 单个2cm方块精度: 0.024
```python
img1 = cv2.imread(imgs[1])
img1.shape
```
(1840, 3264, 3)
```python
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (9,9), 0)
# _, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, thresh = cv2.threshold(blur, 150, 255, 0)
cv2.namedWindow("thresh", cv2.WINDOW_NORMAL)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
```python
ob = objectFound()
rects = ob.rectangle(img1.copy(), thresh, debug=True, mode='all')
```
```python
maxrate = 0
roiF = None
for index, rect in enumerate(rects):
#计算0-255比例, 0要尽可能多
x,y,w,h = rect
roi = thresh[y:y+h, x:x+w]
rate = (np.sum(roi==0)/(roi.shape[0]*roi.shape[1])) + (0.1-index*0.01) #排名奖励
if rate > maxrate:
maxrate = rate
roiF = roi
cv2.imshow("roi", roiF)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
```python
print("计算mm/pixel : {},{},{}".format(20/roiF.shape[0], 20/roiF.shape[1], 0))
```
计算mm/pixel : 0.024509803921568627,0.024009603841536616,0
## 角点检测
* 过滤出符合条件的角点,定义了一个筛选方法
```python
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (15,15), 0)
# _, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, thresh = cv2.threshold(blur, 150, 255, 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(12, 12))
erode = cv2.erode(thresh, kernel, 1)
mask = cv2.cornerHarris(erode, 40, 3, 0.04)
#result is dilated for marking the corners, not important
mask = cv2.dilate(mask,None)
# Threshold for an optimal value, it may vary depending on the image.
img11 = img1.copy()
img11[mask>0.01*mask.max()]=[0,0,255]
cv2.namedWindow("corner", cv2.WINDOW_NORMAL)
cv2.imshow("corner", img11)
cv2.imshow("erode", erode)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
```python
gray1 = np.zeros_like(gray)
gray1[mask>0.01*mask.max()]=255
_, labels, stats, centroids = cv2.connectedComponentsWithStats(gray1)
cv2.namedWindow("labels", cv2.WINDOW_NORMAL)
cv2.imshow("labels", labels)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
## 定义筛选函数
```python
def exitHelper(roi):
"""左右两个边孤岛和为3,上下同理"""
h,w = roi.shape
edge1 = roi[0:h-1, 0:10] #左
edge2 = roi[0:h-1, w-10:w-1]#右
edge3 = roi[0:10, 0:w-1] #上
edge4 = roi[h-10:h-1, 0:w-1] #下
connected255 = 0
_, labels, stats, centroids1 = cv2.connectedComponentsWithStats(edge1)
_, labels, stats, centroids2 = cv2.connectedComponentsWithStats(edge2)
if len(centroids2) + len(centroids1) == 3:
_, labels, stats, centroids1 = cv2.connectedComponentsWithStats(edge3)
_, labels, stats, centroids2 = cv2.connectedComponentsWithStats(edge4)
if len(centroids2) + len(centroids1) == 3:
return True
return False
wsize=100
result = []
for p in centroids:
x,y = int(np.round(p[0])), int(np.round(p[1]))
x1, y1, x2, y2 = x-wsize, y-wsize, x+wsize, y+wsize
if x
if y
roi = thresh[y1:y2, x1:x2]
if exitHelper(roi):
result.append(p)
cv2.imshow("roi", roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
```python
#试算扫描线宽
wsize=100
step = 10 #pixel
data = []
for p in result:
x,y = int(np.round(p[0])), int(np.round(p[1]))
x1, y1, x2, y2 = x-wsize, y-wsize, x+wsize, y+wsize
if x
if y
roi = thresh[y1:y2, x1:x2]
h, w = roi.shape
widthList = []
#左右扫描
cnts = []
for i in range(0, w, step):
# print(roi[0:h, i])
if np.sum(roi[0:h, i])/255 < wsize and np.sum(roi[0:h, i])/255 > 0:
cnts.append(np.sum(roi[0:h, i])/255)
widthList.append([(x1+i, y1), cnts])
#上下扫描
cnts = []
for i in range(0, h, step):
# print(roi[i, 0:w])
if np.sum(roi[i, 0:w])/255 < wsize and np.sum(roi[i, 0:w])/255 > 0:
cnts.append(np.sum(roi[i, 0:w])/255)
widthList.append([(x1, y1+i), cnts])
data.append(widthList)
```
```python
img11 = img1.copy()
for line in data:
for d in line:
p, cnts = d
cv2.circle(img11, p, 3, (0,255,0), 1)
cv2.putText(img11,'{:.2f}'.format(np.median(cnts)*0.024), (p[0]+5,p[1]+5),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)
cv2.imwrite( "../day2.jpg", img11)
cv2.namedWindow("result", cv2.WINDOW_NORMAL)
cv2.imshow("result", img11)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
```python
dataset={
"lineA":{
"width":[1.06,1.34,1.46,1.49,1.52,1.54,1.49,1.39,1.48,1.39,1.50,1.41,1.34,1.37,1.39,1.36,1.40,1.28,1.26]
},
"lineB":{
"width":[1.15,1.24,1.19,1.25,1.33,1.29,1.36,1.17,1.31,1.33,1.37,1.32,1.37,1.44,1.37,1.4,1.43]
}
}
```