Skip to content

Commit 2af5a1f

Browse files
committed
add 71~75
1 parent 5bb2f56 commit 2af5a1f

25 files changed

+319
-0
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,8 @@ code_067 | [Top Hat](python/code_067/opencv_067.py) | ✔️
109109
code_068 | [Black Hat](python/code_068/opencv_068.py) | ✔️
110110
code_069 | [Morph Gradient](python/code_069/opencv_069.py) | ✔️
111111
code_070 | [Contour based on Morph Gradient](python/code_070/opencv_070.py) | ✏️
112+
code_071 | [Hit and Miss](python/code_071/opencv_071.py) | ✔️
113+
code_072 | [Defect Detecting-1](python/code_072/opencv_072.py) | ✔️
114+
code_073 | [Defect Detecting-2](python/code_073/opencv_073.py) | ✔️
115+
code_074 | [Extract the Maximum Contour and Coding Key Points](python/code_074/opencv_074.py) | ✔️
116+
code_075 | [Image Inpainting](python/code_075/opencv_075.py) | ✔️

README_CN.md

+5
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,8 @@ code_067 | [顶帽](python/code_067/opencv_067.py) | ✔️
108108
code_068 | [黑帽](python/code_068/opencv_068.py) | ✔️
109109
code_069 | [图像梯度](python/code_069/opencv_069.py) | ✔️
110110
code_070 | [基于梯度的轮廓发现](python/code_070/opencv_070.py) | ✏️
111+
code_071 | [击中击不中](python/code_071/opencv_071.py) | ✔️
112+
code_072 | [缺陷检测1](python/code_072/opencv_072.py) | ✔️
113+
code_073 | [缺陷检测2](python/code_073/opencv_073.py) | ✔️
114+
code_074 | [提取最大轮廓和编码关键点](python/code_074/opencv_074.py) | ✔️
115+
code_075 | [图像修复](python/code_075/opencv_075.py) | ✔️

python/code_071/binary2.png

2.62 KB
Loading

python/code_071/cross.png

205 KB
Loading

python/code_071/opencv_071.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import cv2 as cv
2+
import numpy as np
3+
4+
src = cv.imread("cross.png")
5+
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
6+
cv.imshow("input", src)
7+
8+
# Binary image
9+
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
10+
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
11+
12+
# Hit and Miss
13+
se = cv.getStructuringElement(cv.MORPH_CROSS, (12, 12))
14+
binary = cv.morphologyEx(binary, cv.MORPH_HITMISS, se)
15+
16+
17+
cv.imshow("hit miss", binary)
18+
cv.imwrite("binary2.png", binary)
19+
20+
cv.waitKey(0)
21+
cv.destroyAllWindows()

python/code_072/README.md

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#### 二值图像分析 – 缺陷检测
2+
3+
1. 观察图像与提取图像ROI对象轮廓外接矩形与轮廓.
4+
```python
5+
# Get contours
6+
_, contours, hierarchy = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
7+
height, width = src.shape[:2]
8+
for c in range(len(contours)):
9+
x, y, w, h = cv.boundingRect(contours[c])
10+
area = cv.contourArea(contours[c])
11+
if h > (height//2):
12+
continue
13+
if area < 150:
14+
continue
15+
cv.rectangle(src, (x, y), (x+w, y+h), (0, 0, 255), 1, 8, 0)
16+
cv.drawContours(src, contours, c, (0, 255, 0), 2, 8)
17+
```
18+
<img src=ce_02.jpg width=300>
19+
<img src=binary2.png width=300>
20+
21+
2. 对于得到的刀片外接矩形,首先需要通过排序,确定他们的编号.
22+
23+
👀 [代码Code](../code_073/opencv_073.py)
24+
25+
```
26+
# 排序轮廓
27+
rects = sorted(rects, key = lambda x:x[1])
28+
```
29+
3. 根据模板进行相减得到与模板不同的区域,对这些区域进行形态学操作,去掉边缘细微差异,最终就得到了可以检出的缺陷或者划痕刀片。
30+
31+
```python
32+
# 获取模板
33+
def get_template(binary, boxes):
34+
x, y, w, h = boxes[0]
35+
roi = binary[y:y+h, x:x+w]
36+
return roi
37+
38+
# 缺陷检测函数
39+
def detect_defect(binary, boxes, tpl):
40+
height, width = tpl.shape
41+
index = 1
42+
defect_rois = []
43+
# 发现缺失
44+
for x, y, w, h in boxes:
45+
roi = binary[y:y + h, x:x + w]
46+
roi = cv.resize(roi, (width, height))
47+
mask = cv.subtract(tpl, roi)
48+
se = cv.getStructuringElement(cv.MORPH_RECT, (5, 5), (-1, -1))
49+
mask = cv.morphologyEx(mask, cv.MORPH_OPEN, se)
50+
ret, mask = cv.threshold(mask, 0, 255, cv.THRESH_BINARY)
51+
count = 0
52+
for row in range(height):
53+
for col in range(width):
54+
pv = mask[row, col]
55+
if pv == 255:
56+
count += 1
57+
if count > 0:
58+
defect_rois.append([x, y, w, h])
59+
cv.imwrite("mask%d.png"%index, mask)
60+
index += 1
61+
return defect_rois
62+
63+
```
64+
65+
<img src=../code_073/ce_02.jpg width=300>
66+
<img src=../code_073/binary2.png width=300>

python/code_072/binary2.png

240 KB
Loading

python/code_072/ce_02.jpg

27.2 KB
Loading

python/code_072/opencv_072.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import cv2 as cv
2+
import numpy as np
3+
4+
src = cv.imread("ce_02.jpg")
5+
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
6+
cv.imshow("input", src)
7+
8+
# get binary
9+
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
10+
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
11+
12+
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3), (-1, -1))
13+
binary = cv.morphologyEx(binary, cv.MORPH_OPEN, se)
14+
cv.imshow("binary", binary)
15+
16+
# Get contours
17+
_, contours, hierarchy = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
18+
height, width = src.shape[:2]
19+
for c in range(len(contours)):
20+
x, y, w, h = cv.boundingRect(contours[c])
21+
area = cv.contourArea(contours[c])
22+
if h > (height//2):
23+
continue
24+
if area < 150:
25+
continue
26+
cv.rectangle(src, (x, y), (x+w, y+h), (0, 0, 255), 1, 8, 0)
27+
cv.drawContours(src, contours, c, (0, 255, 0), 2, 8)
28+
29+
cv.imshow("result", src)
30+
cv.imwrite("binary2.png", src)
31+
32+
cv.waitKey(0)
33+
cv.destroyAllWindows()

python/code_073/binary2.png

248 KB
Loading

python/code_073/ce_02.jpg

27.2 KB
Loading

python/code_073/mask1.png

158 Bytes
Loading

python/code_073/mask2.png

198 Bytes
Loading

python/code_073/mask3.png

176 Bytes
Loading

python/code_073/mask4.png

158 Bytes
Loading

python/code_073/opencv_073.py

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import cv2 as cv
2+
import numpy as np
3+
4+
def get_template(binary, boxes):
5+
x, y, w, h = boxes[0]
6+
roi = binary[y:y+h, x:x+w]
7+
return roi
8+
9+
10+
def detect_defect(binary, boxes, tpl):
11+
height, width = tpl.shape
12+
index = 1
13+
defect_rois = []
14+
# 发现缺失
15+
for x, y, w, h in boxes:
16+
roi = binary[y:y + h, x:x + w]
17+
roi = cv.resize(roi, (width, height))
18+
mask = cv.subtract(tpl, roi)
19+
se = cv.getStructuringElement(cv.MORPH_RECT, (5, 5), (-1, -1))
20+
mask = cv.morphologyEx(mask, cv.MORPH_OPEN, se)
21+
ret, mask = cv.threshold(mask, 0, 255, cv.THRESH_BINARY)
22+
count = 0
23+
for row in range(height):
24+
for col in range(width):
25+
pv = mask[row, col]
26+
if pv == 255:
27+
count += 1
28+
if count > 0:
29+
defect_rois.append([x, y, w, h])
30+
cv.imwrite("mask%d.png"%index, mask)
31+
index += 1
32+
return defect_rois
33+
34+
35+
src = cv.imread("ce_02.jpg")
36+
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
37+
cv.imshow("input", src)
38+
39+
# 图像二值化
40+
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
41+
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
42+
43+
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3), (-1, -1))
44+
binary = cv.morphologyEx(binary, cv.MORPH_OPEN, se)
45+
cv.imshow("binary", binary)
46+
47+
# 轮廓提取
48+
out, contours, hierarchy = cv.findContours(binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
49+
height, width = src.shape[:2]
50+
rects = []
51+
for c in range(len(contours)):
52+
x, y, w, h = cv.boundingRect(contours[c])
53+
area = cv.contourArea(contours[c])
54+
if h > (height//2):
55+
continue
56+
if area < 150:
57+
continue
58+
rects.append([x, y, w, h])
59+
60+
# 排序轮廓
61+
rects = sorted(rects, key = lambda x:x[1])
62+
print(rects)
63+
template = get_template(binary, rects);
64+
65+
# 填充边缘
66+
for c in range(len(contours)):
67+
x, y, w, h = cv.boundingRect(contours[c])
68+
area = cv.contourArea(contours[c])
69+
if h > (height//2):
70+
continue
71+
if area < 150:
72+
continue
73+
cv.drawContours(binary, contours, c, (0), 2, 8)
74+
cv.imshow("template", template)
75+
76+
# 检测缺陷
77+
defect_boxes = detect_defect(binary, rects, template)
78+
for dx, dy, dw, dh in defect_boxes:
79+
cv.rectangle(src, (dx, dy), (dx + dw, dy + dh), (0, 0, 255), 1, 8, 0)
80+
cv.putText(src, "bad", (dx, dy-2), cv.FONT_HERSHEY_SIMPLEX, .5, (0, 255, 0), 2)
81+
82+
index = 1
83+
for dx, dy, dw, dh in rects:
84+
cv.putText(src, "num:%d"%index, (dx-52, dy+30), cv.FONT_HERSHEY_SIMPLEX, .5, (30, 122, 233), 2)
85+
index += 1
86+
87+
cv.imshow("result", src)
88+
cv.imwrite("binary2.png", src)
89+
90+
cv.waitKey(0)
91+
cv.destroyAllWindows()

python/code_074/README.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#### 二值图像分析 – 提取最大轮廓与编码关键点
2+
3+
1. 二值化处理
4+
```python
5+
# src = cv.GaussianBlur(src, (5, 5), 0)
6+
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
7+
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
8+
9+
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3), (-1, -1))
10+
binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, se)
11+
```
12+
13+
2. 寻找最大面积的轮廓
14+
```python
15+
# 轮廓提取
16+
out, contours, hierarchy = cv.findContours(binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
17+
height, width = src.shape[:2]
18+
index = 0
19+
max = 0
20+
for c in range(len(contours)):
21+
x, y, w, h = cv.boundingRect(contours[c])
22+
if h >=height or w >= width:
23+
continue
24+
area = cv.contourArea(contours[c])
25+
if area > max:
26+
max = area
27+
index = c
28+
```
29+
3. 输出
30+
31+
<img src=result.png width=300>
32+
<img src=output.png width=300>

python/code_074/case6.jpg

110 KB
Loading

python/code_074/opencv_074.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import cv2 as cv
2+
import numpy as np
3+
4+
src = cv.imread("case6.jpg")
5+
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
6+
cv.imshow("input", src)
7+
8+
# 图像二值化
9+
# src = cv.GaussianBlur(src, (5, 5), 0)
10+
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
11+
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
12+
13+
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3), (-1, -1))
14+
binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, se)
15+
cv.imshow("binary", binary)
16+
17+
# 轮廓提取
18+
out, contours, hierarchy = cv.findContours(binary, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
19+
height, width = src.shape[:2]
20+
index = 0
21+
max = 0
22+
for c in range(len(contours)):
23+
x, y, w, h = cv.boundingRect(contours[c])
24+
if h >=height or w >= width:
25+
continue
26+
area = cv.contourArea(contours[c])
27+
if area > max:
28+
max = area
29+
index = c
30+
31+
print(index)
32+
33+
# 绘制轮廓关键点与轮廓
34+
result = np.zeros(src.shape, dtype=np.uint8)
35+
keypts = cv.approxPolyDP(contours[index], 4, True)
36+
cv.drawContours(src, contours, index, (0, 0, 255), 1, 8)
37+
cv.drawContours(result, contours, index, (0, 0, 255), 1, 8)
38+
#print(keypts)
39+
for pt in keypts:
40+
cv.circle(src, (pt[0][0], pt[0][1]), 2, (0, 255, 0), 2, 8, 0)
41+
cv.circle(result, (pt[0][0], pt[0][1]), 2, (0, 255, 0), 2, 8, 0)
42+
cv.imshow("result", result)
43+
cv.imshow("output", src)
44+
cv.imwrite("result.png", result)
45+
cv.imwrite("output.png", src)
46+
47+
cv.waitKey(0)
48+
cv.destroyAllWindows()

python/code_074/output.png

775 KB
Loading

python/code_074/result.png

8.08 KB
Loading

python/code_075/mask.png

4.6 KB
Loading

python/code_075/master2.jpg

68.4 KB
Loading

python/code_075/opencv_075.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import cv2 as cv
2+
3+
src = cv.imread("master2.jpg")
4+
cv.imshow("watermark image", src)
5+
# 提取划痕
6+
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
7+
mask = cv.inRange(hsv, (100, 43, 46), (124, 255, 255))
8+
cv.imshow("mask", mask)
9+
cv.imwrite("mask.png", mask)
10+
11+
# 消除
12+
se = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
13+
mask = cv.dilate(mask, se)
14+
result = cv.inpaint(src, mask, 3, cv.INPAINT_TELEA)
15+
cv.imshow("result", result)
16+
cv.imwrite("result.png", result)
17+
cv.waitKey(0)
18+
cv.destroyAllWindows()

python/code_075/result.png

343 KB
Loading

0 commit comments

Comments
 (0)