算法学习

该部分内容基本与讨论纪要相同,这里引用一下

讨论纪要

核心思路

划分区域的分界线应与较大区分度的连线重合

所以由此可得出一种可能可行的方案:若这两种连线不符,则存在干扰点

实行步骤

取5X5的像素点,以2X2方格为一个单位,找出5-6个边缘单位与前6个区分度大的单位,若不相符,则区分度最大的单位就标记为噪声(这里我并不清楚究竟要标记哪一个点,因为一个单位有四个点

求出边缘单位

以2X2个像素点为一个单位,进行区域划分,将该步骤抽象为“剪断差值大的边”,将“剪断边”的地方视为通路,将多个通路连通,形成边缘线(这步操作的难点在于:1.不知道是不是一定会存在这样的通路;2.遍历每个单位格的效率存在问题;3.需要进一步思考,要将通路以什么样的方式存储,后面步骤比较

求出较大区分度单位

求该步比较简单(最大问题与上面的3相同,需要进一步考虑存储区分度的问题

代码实现

读取test1.png,找出噪声值,并输出到output.txt

test1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# python解释器:anaconda3/python3.8
# 编译器:pycharm
# utf-8

import cv2 as cv
import numpy as np

# 像素点数组
Pixel_type = np.dtype({
'names': ['value', 'noise'],
'formats': ['i', 'i']
})

# 单位方格数组
Grid_type = np.dtype({
'names': ['division_degree', 'big_degree', 'up', 'down', 'left', 'right', 'step'],
'formats': ['i', 'i', 'i', 'i', 'i', 'i', 'i']
})


def print_file(image_array, x, y):
fp = open('output.txt', 'w')
for i in range(0, x):
for j in range(0, y):
print(image_array[i][j]['noise'], end='', file=fp)
print('', file=fp)
print("导出成功")


def find_road(four_grid, mi, mj, step):
if 0 <= mi - 1 < 4 and \
0 <= mj < 4 and \
four_grid[mi][mj]['up'] == 1 and \
four_grid[mi - 1][mj]['down'] == 1 and \
four_grid[mi - 1][mj]['step'] == 0:
if step + 1 <= 6:
four_grid[mi - 1][mj]['step'] = step + 1
four_grid[mi - 1][mj]['down'] = 0
four_grid = find_road(four_grid, mi - 1, mj, step + 1)
elif 0 <= mi + 1 < 4 and \
0 <= mj < 4 and \
four_grid[mi][mj]['down'] == 1 and \
four_grid[mi + 1][mj]['up'] == 1 and \
four_grid[mi + 1][mj]['step'] == 0:
if step + 1 <= 6:
four_grid[mi + 1][mj]['step'] = step + 1
four_grid[mi + 1][mj]['up'] = 0
four_grid = find_road(four_grid, mi + 1, mj, step + 1)
elif 0 <= mi < 4 and \
0 <= mj - 1 < 4 and \
four_grid[mi][mj]['left'] == 1 and \
four_grid[mi][mj - 1]['right'] == 1 and \
four_grid[mi][mj - 1]['step'] == 0:
if step + 1 <= 6:
four_grid[mi][mj - 1]['step'] = step + 1
four_grid[mi][mj - 1]['right'] = 0
four_grid = find_road(four_grid, mi, mj - 1, step + 1)
elif 0 <= mi < 4 and \
0 <= mj + 1 < 4 and \
four_grid[mi][mj]['right'] == 1 and \
four_grid[mi][mj + 1]['left'] == 1 and \
four_grid[mi][mj + 1]['step'] == 0:
if step + 1 <= 6:
four_grid[mi][mj + 1]['step'] = step + 1
four_grid[mi][mj + 1]['left'] = 0
four_grid = find_road(four_grid, mi, mj + 1, step + 1)
return four_grid


# 分割通路和检测区分度
def division_check(five_matrix):
# 建立单位方格数组
four_grid = np.zeros((4, 4), dtype=Grid_type)
for i in range(0, 4):
for j in range(0, 4):
# 取出四个像素点组成一个单位
p = [five_matrix[i][j]['value'],
five_matrix[i][j + 1]['value'],
five_matrix[i + 1][j + 1]['value'],
five_matrix[i + 1][j]['value']]
p1 = [p[0] - p[1], p[1] - p[2], p[2] - p[3], p[3] - p[0]]
# 找出分割边
max_index = p1.index(max(p1))
min_index = p1.index(min(p1))
# 划分区域
maxa = []
mina = []
if max_index > min_index:
for k in range(min_index + 1, max_index + 1):
maxa.append(p[k])
for k in range(0, min_index + 1):
mina.append(p[k])
for k in range(max_index + 1, 4):
mina.append(p[k])
elif max_index < min_index:
for k in range(max_index + 1, min_index + 1):
mina.append(p[k])
for k in range(0, max_index + 1):
maxa.append(p[k])
for k in range(min_index + 1, 4):
maxa.append(p[k])
# 求区分度
if len(maxa) == 0 or len(mina) == 0:
break
four_grid[i][j]['division_degree'] = min(maxa) - max(mina)
# 存储分割边,赋值为1表示是分割边
if max_index == 0 or min_index == 0:
four_grid[i][j]['up'] = 1
if max_index == 1 or min_index == 1:
four_grid[i][j]['right'] = 1
if max_index == 2 or min_index == 2:
four_grid[i][j]['down'] = 1
if max_index == 3 or min_index == 3:
four_grid[i][j]['left'] = 1
# 求出较大区分度
p = []
for i in range(0, 4):
for j in range(0, 4):
p.append(four_grid[i][j]['division_degree'])
p = sorted(p, reverse=True)
# 找出第6大的那个值,找出最大值的位置
pmax = p[0]
mi = 0
mj = 0
px = p[5]
for i in range(0, 4):
for j in range(0, 4):
# 将前6个较大的标记
if four_grid[i][j]['division_degree'] >= px:
four_grid[i][j]['big_degree'] = 1
# 找出最大值的下标
if four_grid[i][j]['division_degree'] == pmax:
mi = i
mj = j
# 以最大值为起点,找通路(利用递归算法)
four_grid[mi][mj]['step'] = 1
new_grid = find_road(four_grid, mi, mj, 1)
# 找出干扰点
for i in range(4):
for j in range(4):
if new_grid[i][j]['big_degree'] == 1 and new_grid[i][j]['step'] == 0:
ave = (five_matrix[i][j]['value'] +
five_matrix[i + 1][j]['value'] +
five_matrix[i][j + 1]['value'] +
five_matrix[i + 1][j + 1]['value']) / 4
xmax = 0
pi = 0
pj = 0
if abs(five_matrix[i][j]['value'] - ave) > xmax:
xmax = abs(five_matrix[i][j]['value'] - ave)
pi = i
pj = j
if abs(five_matrix[i+1][j]['value'] - ave) > xmax:
xmax = abs(five_matrix[i+1][j]['value'] - ave)
pi = i+1
pj = j
if abs(five_matrix[i][j+1]['value'] - ave) > xmax:
xmax = abs(five_matrix[i][j+1]['value'] - ave)
pi = i
pj = j+1
if abs(five_matrix[i+1][j+1]['value'] - ave) > xmax:
xmax = abs(five_matrix[i+1][j+1]['value'] - ave)
pi = i+1
pj = j+1
five_matrix[pi][pj]['noise'] += 1
return five_matrix


# 检测噪声
def noise_check(image_channel):
# 检测该图像通道的大小
(x, y) = image_channel.shape
# 建立像素点数组,并存入像素值
image_array = np.zeros((x, y), dtype=Pixel_type)
for i in range(0, x):
for j in range(0, y):
image_array[i, j]['value'] = image_channel[i, j]
# 划分单位方格区域,并求出通路和区分度
px = (x // 5) * 5
py = (y // 5) * 5
for i in range(0, px - 4, 5):
for j in range(0, py - 4, 5):
# 每次取出5*5的矩阵
five_matrix = np.zeros((5, 5), dtype=Pixel_type)
for m in range(0, 5):
for n in range(0, 5):
five_matrix[m][n] = image_array[i + m][j + n]
# 检测出噪声
noise_matrix = division_check(five_matrix)
for m in range(0, 5):
for n in range(0, 5):
image_array[m+i][n+j]['noise'] = noise_matrix[m][n]['noise']
# 输出噪声
print_file(image_array, x, y)
return


if __name__ == '__main__':
# 以BGR方式读入图片
image = cv.imread("test1.png", 1)

# 分离图像通道
B, G, R = cv.split(image)

# 检查干扰点(以B通道为例)
noise_check(B)