Skip to content

Commit cd0ccb4

Browse files
committed
Upload CV1
1 parent d3e758f commit cd0ccb4

File tree

11 files changed

+375
-0
lines changed

11 files changed

+375
-0
lines changed
Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
---
2+
title: 计算机视觉 - 1.数元素数目
3+
date: 2024-03-18 09:44:08 +0800
4+
categories: [Python, CV]
5+
tags: [Python, CV] # TAG names should always be lowercase
6+
---
7+
8+
# 计算机视觉1 - 数元素数目
9+
10+
## 0. 任务目标
11+
12+
1. 统计每幅图中各化学元素的数目;
13+
2. 统计AI和Fe元素、Fe和P元素、AI和P元素重叠的数目,并且以图像的形式展示出两两元素的重叠情况;
14+
3. 统计AI、Fe和P元素三者重叠的数目,并以图像的形式展示出三种元素重叠情况。
15+
4. 无论原始图像中的化学元素是何种颜色,均可实现本目标。
16+
17+
## 1. 实现任务
18+
19+
计算机视觉常用的方法是使用OpenCV的库函数对图像进行处理。因此我们先利用 `cv2.imread()` 函数读入图像数据。本例子中,共拥有3张图片,分别是Al,Fe和P(即铝、铁、磷)三种化学元素。下面是三张照片的样子。
20+
21+
<img src="D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\Al.jpg" alt="Al" style="zoom:50%;" />
22+
23+
<img src="D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\Fe.jpg" alt="Fe" style="zoom:50%;" />
24+
25+
<img src="D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\P.jpg" alt="P" style="zoom:50%;" />
26+
27+
读取的代码如下:
28+
29+
```python
30+
# Set paths
31+
al_path = os.path.join('image', 'Al.jpg')
32+
fe_path = os.path.join('image', 'Fe.jpg')
33+
p_path = os.path.join('image', 'P.jpg')
34+
35+
# Read images
36+
al = cv2.imread(al_path)
37+
fe = cv2.imread(fe_path)
38+
p = cv2.imread(p_path)
39+
```
40+
41+
注意,这里的路径最好不要直接写死,而是用python os库中提供的 `os.path.join()` 函数进行拼接处理。该函数能够自行判断当前运行环境而选择路径的分隔符,无论是Linux还是Windows都不会出错。
42+
43+
---
44+
45+
读入图片后,我们发现图片中的左上角logo处和左下角的 50nm 标识都不是我们需要的东西,需要剔除。因此我们需要对输入图像进行预处理:
46+
47+
- 为了去除左上角的logo,根据观察可以看到,logo读取进来的图像矩阵所在的行数均在74行及以内,因此我们处理的时候可以针对logo所在的行数进行删除。
48+
49+
- 为了去除左下角的 50nm 标识,我们需要识别出白色区域并去除。
50+
51+
为了实现上面的目标,我们先将图片从RGB色彩通道转换为HSV(HSB)色彩通道。OpenCV的库函数也提供了相应的转换。我们平常所见的图片绝大多数都是RGB通道,即利用Red(红)、Green(绿)、Blue(蓝)三种颜色及其浓度来表示一张彩色图片。在8Bit色深的RGB图像中,RGB三个通道的取值区间均为[0, 255]。而HSV色彩通道是利用Hue(色调)、Saturation(饱和度)、Value(明度)三值来表示颜色。不同于RGB图像,HSV图像是根据色调H来确定颜色的,而RGB图像一般需要通过三个值共同参与来表达一种颜色。
52+
53+
处理代码如下:
54+
55+
```python
56+
# RGB TO HSV
57+
def rgb2hsv(img):
58+
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
59+
# split H, S, V
60+
h, s, v = cv2.split(hsv_img)
61+
return [h, s, v]
62+
```
63+
64+
显示HSV图像三通道的代码如下:
65+
66+
```python
67+
def show_hsv_image(imgs: list):
68+
cv2.imshow('H', imgs[0])
69+
cv2.imshow('S', imgs[1])
70+
cv2.imshow('V', imgs[2])
71+
cv2.waitKey(0)
72+
cv2.destroyAllWindows()
73+
```
74+
75+
未经处理前,Al的分拆HSV通道后的图像如下:
76+
77+
![Al的HSV图像](D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\Al的HSV图像.png)
78+
79+
在HSV图像中,查询可知黑色点范围如下:
80+
81+
- H: [0, 180]
82+
- S: [0, 255]
83+
- V: [0, 46]
84+
85+
白色点范围如下:
86+
87+
- H: [0, 180]
88+
- S: [0, 30]
89+
- V: [221, 255]
90+
91+
logo区域的像素点较为明亮,因此可以直接利用位置和V的值进行判断去除。
92+
93+
图像预处理代码如下:
94+
95+
```python
96+
def remove_light(split_img: list):
97+
h, s, v = split_img
98+
for i in range(h.shape[0]):
99+
for j in range(h.shape[1]):
100+
# Remove black points
101+
if 0 <= h[i, j] <= 180 and 0 <= v[i, j] <= 46:
102+
h[i, j] = 0
103+
s[i, j] = 0
104+
v[i, j] = 0
105+
# Remove white points
106+
elif 0 <= h[i, j] <= 180 and 221 <= v[i, j] <= 255 and 0 <= s[i, j] <= 30:
107+
h[i, j] = 0
108+
s[i, j] = 0
109+
v[i, j] = 0
110+
# Remove logo area
111+
if i <= 70 and 180 <= v[i, j] <= 255:
112+
h[i, j] = 0
113+
s[i, j] = 0
114+
v[i, j] = 0
115+
116+
return [h, s, v]
117+
```
118+
119+
---
120+
121+
统计元素量时,为了方便统计,我们把有颜色的像素点都统计为1个元素。而我们已在上一步去除了杂色点,因此这一步可以直接数图像V通道的点数进行统计。统计函数如下:
122+
123+
```python
124+
# Counting
125+
def count_points(img: list):
126+
h, s, v = img
127+
counter = 0
128+
for i in range(v.shape[0]):
129+
for j in range(v.shape[1]):
130+
if v[i, j] != 0:
131+
counter += 1
132+
133+
return counter
134+
```
135+
136+
---
137+
138+
统计重叠量时,依旧是利用上一步的思想进行统计,但是这时候我们需要两张图片的交集,即需要多加一个“与”的判断步骤。为了显示图片,我们还需要返回合并后的HSV矩阵。
139+
140+
```python
141+
def count2overlap(img1: list, img2: list):
142+
h1, s1, v1 = img1
143+
h2, s2, v2 = img2
144+
h0 = np.zeros(h1.shape, dtype=np.uint8)
145+
s0 = np.zeros(s1.shape, dtype=np.uint8)
146+
v0 = np.zeros(v1.shape, dtype=np.uint8)
147+
counter = 0
148+
for i in range(v1.shape[0]):
149+
for j in range(v1.shape[1]):
150+
if v1[i, j] != 0 and v2[i, j] != 0:
151+
h0[i, j] = h1[i, j] + h2[i, j]
152+
s0[i, j] = s1[i, j] + s2[i, j]
153+
v0[i, j] = v1[i, j] + v2[i, j]
154+
counter += 1
155+
156+
return counter, [h0, s0, v0]
157+
```
158+
159+
三张图片的元素重叠量也是同理。
160+
161+
```python
162+
def count3overlap(img1: list, img2: list, img3: list):
163+
h1, s1, v1 = img1
164+
h2, s2, v2 = img2
165+
h3, s3, v3 = img3
166+
h0 = np.zeros(h1.shape, dtype=np.uint8)
167+
s0 = np.zeros(s1.shape, dtype=np.uint8)
168+
v0 = np.zeros(v1.shape, dtype=np.uint8)
169+
counter = 0
170+
for i in range(v1.shape[0]):
171+
for j in range(v1.shape[1]):
172+
if v1[i, j] != 0 and v2[i, j] != 0 and v3[i, j] != 0:
173+
h0[i, j] = h1[i, j] + h2[i, j] + h3[i, j]
174+
s0[i, j] = s1[i, j] + s2[i, j] + s3[i, j]
175+
v0[i, j] = v1[i, j] + v2[i, j] + v3[i, j]
176+
counter += 1
177+
178+
return counter, [h0, s0, v0]
179+
```
180+
181+
至此,我们本例子的目标基本完成。由于我们将重要的功能封装成函数且与具体颜色无关,因此无论原始图像中的化学元素是何种颜色,只需修改图像路径,均可实现本目标。
182+
183+
---
184+
185+
完整代码如下:
186+
187+
```python
188+
import os.path
189+
import cv2
190+
import numpy as np
191+
import matplotlib.pyplot as plt
192+
193+
# Set paths
194+
al_path = os.path.join('image', 'Al.jpg')
195+
fe_path = os.path.join('image', 'Fe.jpg')
196+
p_path = os.path.join('image', 'P.jpg')
197+
198+
# Read images
199+
al = cv2.imread(al_path)
200+
fe = cv2.imread(fe_path)
201+
p = cv2.imread(p_path)
202+
203+
204+
# RGB TO HSV
205+
def rgb2hsv(img):
206+
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
207+
# split H, S, V
208+
h, s, v = cv2.split(hsv_img)
209+
return [h, s, v]
210+
211+
212+
# Plot image
213+
def show_image3(imgs: list):
214+
plt.figure(figsize=(15, 15))
215+
for i, img in enumerate(imgs):
216+
plt.subplot(1, 3, i + 1)
217+
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
218+
plt.axis('off')
219+
plt.show()
220+
221+
222+
# Plot HSV image
223+
def show_hsv_image(imgs: list):
224+
cv2.imshow('H', imgs[0])
225+
cv2.imshow('S', imgs[1])
226+
cv2.imshow('V', imgs[2])
227+
cv2.waitKey(0)
228+
cv2.destroyAllWindows()
229+
230+
231+
# Remove black and white points and logo
232+
def remove_light(split_img: list):
233+
h, s, v = split_img
234+
for i in range(h.shape[0]):
235+
for j in range(h.shape[1]):
236+
# Remove black points
237+
if 0 <= h[i, j] <= 180 and 0 <= v[i, j] <= 46:
238+
h[i, j] = 0
239+
s[i, j] = 0
240+
v[i, j] = 0
241+
# Remove white points
242+
elif 0 <= h[i, j] <= 180 and 221 <= v[i, j] <= 255 and 0 <= s[i, j] <= 30:
243+
h[i, j] = 0
244+
s[i, j] = 0
245+
v[i, j] = 0
246+
# Remove logo area
247+
if i <= 70 and 180 <= v[i, j] <= 255:
248+
h[i, j] = 0
249+
s[i, j] = 0
250+
v[i, j] = 0
251+
252+
return [h, s, v]
253+
254+
255+
# Counting
256+
def count_points(img: list):
257+
h, s, v = img
258+
counter = 0
259+
for i in range(v.shape[0]):
260+
for j in range(v.shape[1]):
261+
if v[i, j] != 0:
262+
counter += 1
263+
264+
return counter
265+
266+
267+
images = [al, fe, p]
268+
# show_image3(images)
269+
270+
hsv_al = rgb2hsv(al)
271+
hsv_fe = rgb2hsv(fe)
272+
hsv_p = rgb2hsv(p)
273+
show_hsv_image(hsv_al)
274+
275+
# pre-process
276+
processed_al = remove_light(hsv_al)
277+
processed_fe = remove_light(hsv_fe)
278+
processed_p = remove_light(hsv_p)
279+
280+
# counting
281+
counter_al = count_points(processed_al)
282+
counter_fe = count_points(processed_fe)
283+
counter_p = count_points(processed_p)
284+
285+
print("Al元素的点数:", counter_al)
286+
print("Fe元素的点数:", counter_fe)
287+
print("P元素的点数:", counter_p)
288+
289+
290+
# 求解重叠量,并将两者的重叠量画出来
291+
def count2overlap(img1: list, img2: list):
292+
h1, s1, v1 = img1
293+
h2, s2, v2 = img2
294+
h0 = np.zeros(h1.shape, dtype=np.uint8)
295+
s0 = np.zeros(s1.shape, dtype=np.uint8)
296+
v0 = np.zeros(v1.shape, dtype=np.uint8)
297+
counter = 0
298+
for i in range(v1.shape[0]):
299+
for j in range(v1.shape[1]):
300+
if v1[i, j] != 0 and v2[i, j] != 0:
301+
h0[i, j] = h1[i, j] + h2[i, j]
302+
s0[i, j] = s1[i, j] + s2[i, j]
303+
v0[i, j] = v1[i, j] + v2[i, j]
304+
counter += 1
305+
306+
return counter, [h0, s0, v0]
307+
308+
309+
# 求解三者的重叠量
310+
def count3overlap(img1: list, img2: list, img3: list):
311+
h1, s1, v1 = img1
312+
h2, s2, v2 = img2
313+
h3, s3, v3 = img3
314+
h0 = np.zeros(h1.shape, dtype=np.uint8)
315+
s0 = np.zeros(s1.shape, dtype=np.uint8)
316+
v0 = np.zeros(v1.shape, dtype=np.uint8)
317+
counter = 0
318+
for i in range(v1.shape[0]):
319+
for j in range(v1.shape[1]):
320+
if v1[i, j] != 0 and v2[i, j] != 0 and v3[i, j] != 0:
321+
h0[i, j] = h1[i, j] + h2[i, j] + h3[i, j]
322+
s0[i, j] = s1[i, j] + s2[i, j] + s3[i, j]
323+
v0[i, j] = v1[i, j] + v2[i, j] + v3[i, j]
324+
counter += 1
325+
326+
return counter, [h0, s0, v0]
327+
328+
329+
# Get 2 overlap
330+
overlap_al_fe, overlap_img_af = count2overlap(processed_al, processed_fe)
331+
overlap_al_p, overlap_img_ap = count2overlap(processed_al, processed_p)
332+
overlap_fe_p, overlap_img_fp = count2overlap(processed_fe, processed_p)
333+
overlap_img_af = cv2.cvtColor(cv2.merge(overlap_img_af), cv2.COLOR_HSV2BGR)
334+
overlap_img_ap = cv2.cvtColor(cv2.merge(overlap_img_ap), cv2.COLOR_HSV2BGR)
335+
overlap_img_fp = cv2.cvtColor(cv2.merge(overlap_img_fp), cv2.COLOR_HSV2BGR)
336+
print("Al和Fe的重叠量:", overlap_al_fe)
337+
print("Al和P的重叠量:", overlap_al_p)
338+
print("Fe和P的重叠量:", overlap_fe_p)
339+
# show_image3([overlap_img_af, overlap_img_ap, overlap_img_fp])
340+
341+
# Get 3 overlap
342+
overlap_all, overlap_img_all = count3overlap(processed_al, processed_fe, processed_p)
343+
overlap_img_all = cv2.cvtColor(cv2.merge(overlap_img_all), cv2.COLOR_HSV2BGR)
344+
print("Al, Fe和P的重叠量:", overlap_all)
345+
# cv2.imshow('Overlay with Al, Fe and P elements', overlap_img_all)
346+
# cv2.waitKey(0)
347+
# cv2.destroyAllWindows()
348+
349+
# Save images
350+
if not os.path.exists('image_out'):
351+
os.makedirs('image_out')
352+
cv2.imwrite(os.path.join('image_out', 'overlap_img_af.jpg'), overlap_img_af)
353+
cv2.imwrite(os.path.join('image_out', 'overlap_img_ap.jpg'), overlap_img_ap)
354+
cv2.imwrite(os.path.join('image_out', 'overlap_img_fp.jpg'), overlap_img_fp)
355+
cv2.imwrite(os.path.join('image_out', 'overlap_img_all.jpg'), overlap_img_all)
356+
357+
```
358+
359+
最终的得到的重叠图片如下:
360+
361+
- Al和Fe:
362+
363+
<img src="D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\overlap_img_af.jpg" alt="overlap_img_af" style="zoom:50%;" />
364+
365+
- Al和P:
366+
367+
<img src="D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\overlap_img_ap.jpg" alt="overlap_img_ap" style="zoom:50%;" />
368+
369+
- Fe和P:
370+
371+
<img src="D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\overlap_img_fp.jpg" alt="overlap_img_fp" style="zoom:50%;" />
372+
373+
- 三者重叠:
374+
375+
<img src="D:\Coder\Github Repos\StandardL.github.io\assets\img\posts\2024-03-18-计算机视觉1\overlap_img_all.jpg" alt="overlap_img_all" style="zoom:50%;" />
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)