利用局部最大区分度

利用局部最大区分度,意图改善部分边缘提取不到的情况

代码示例

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
# utf-8
# python3.8

import cv2 as cv
import numpy as np


def get_unit_similarity(a_4, b_4, k):
# a_4 = sorted(a_4)
# b_4 = sorted(b_4)
result = 0
for i in range(4):
result = result + (abs(int(a_4[i]) - int(b_4[i]))) ** k
result = result ** (1/k)
return int(result)


def input_flag(flag, x, y, similarity):
for i in range(4):
if flag[x][y][i] == 0:
flag[x][y][i] = similarity
break
return flag


def get_channels_similarity(channel, k, rank):
row, col = channel.shape
flag = np.zeros((row - 1, col - 1, 4))
result = np.zeros((row - 1, col - 1))
for i in range(row - 2):
for j in range(col - 2):
array = [channel[i][j], channel[i][j + 1], channel[i + 1][j + 1], channel[i + 1][j]]
r_array = [channel[i][j + 1], channel[i + 1][j + 1], channel[i][j + 2], channel[i + 1][j + 2]]
d_array = [channel[i + 1][j + 1], channel[i + 1][j], channel[i + 2][j + 1], channel[i + 2][j]]
r_similarity = get_unit_similarity(array, r_array, k)
d_similarity = get_unit_similarity(array, d_array, k)
flag = input_flag(flag, i, j, r_similarity)
flag = input_flag(flag, i, j, d_similarity)
flag = input_flag(flag, i+1, j, r_similarity)
flag = input_flag(flag, i, j+1, d_similarity)
# result[i][j] = (r_similarity + d_similarity) / 2
for i in range(row-2):
for j in range(col-2):
flag4 = sorted(flag[i][j])
result[i][j] = flag4[4-rank]
return result


def get_qufendu(array):
return int(max(array)) - int(min(array))


def get_channels_qufendu(channel):
row, col = channel.shape
result = np.zeros((row - 1, col - 1))
for i in range(row-1):
for j in range(col-1):
array = [channel[i][j], channel[i][j + 1], channel[i + 1][j + 1], channel[i + 1][j]]
qufendu = get_qufendu(array)
result[i][j] = qufendu
return result


def is_max_qufendu(qufendu, x, y):
row, col = qufendu.shape
mid_qufendu = qufendu[x][y]
a = []
for i in range(x-1, x+2):
for j in range(y-1, y+2):
if row-1 >= i >= 0 and col-1 >= j >= 0 and qufendu[i][j]:
a.append(abs(int(mid_qufendu) - int(qufendu[i][j])))
if len(a) > 0 and max(a) >= 20:
return True
else:
return False



def mark(channel, similarity, qufendu):
row, col = similarity.shape
for i in range(row):
for j in range(col):
if similarity[i][j] > 50 and qufendu[i][j] > 20:
channel[i][j] = 0
else:
channel[i][j] = 255
if is_max_qufendu(qufendu, i, j):
channel[i][j] = 0
return channel


def mark_similarity(img, k, rank):
p = cv.imread(img, 1)
b, g, r = cv.split(p)
b_similarity = get_channels_similarity(b, k, rank)
b_qufendu = get_channels_qufendu(b)
b = mark(b, b_similarity, b_qufendu)
g_similarity = get_channels_similarity(g, k, rank)
g_qufendu = get_channels_qufendu(g)
g = mark(g, g_similarity, g_qufendu)
r_similarity = get_channels_similarity(r, k, rank)
r_qufendu = get_channels_qufendu(r)
r = mark(r, r_similarity, r_qufendu)
p = cv.merge((b, g, r))
cv.imwrite(img[0:-4] + '_fix_mark.png', p)


if __name__ == '__main__':
img_addr = '8068.jpg'
mark_similarity(img_addr, 1, 1)

效果

image-20220517093022285

image-20220517093133338

结果

这种方法仍然很容易就加粗明显的边缘,而天鹅颈在水下的倒影仍然无法清晰连续