File size: 4,192 Bytes
17dff85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import traceback

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


def get_binary_img_(img):
    gray_img = img
    if len(img.shape) > 2:
        gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    binary_img = cv.Canny(gray_img, 80, 150)
    return binary_img


def get_morp_dilate_(binary_img):
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    # morp_dilate = cv.morphologyEx(binaryImg, cv.MORPH_DILATE, kernel=(1, 3), iterations=3)
    # morp_dilate = cv.morphologyEx(morp_dilate, cv.MORPH_DILATE, kernel=(3, 1), iterations=3)
    # morp_dilate = cv.morphologyEx(binaryImg, cv.MORPH_DILATE, kernel=(11, 11), iterations=3)
    morp_dilate = cv.morphologyEx(binary_img, cv.MORPH_DILATE, kernel=kernel, iterations=3)
    return morp_dilate


def get_water_img_(img, morp_dilate):
    # 寻找图像轮廓 返回修改后的 图像的轮廓  以及它们的层次
    # contours, hierarchy = cv.findContours(gray_img, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    # contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
    # contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    contours, hierarchy = cv.findContours(morp_dilate, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    # 32位有符号整数类型,
    marks = np.zeros(morp_dilate.shape[:2], np.int32)
    # 绘制每一个轮廓
    for index in range(len(contours)):
        # 对marks进行标记,对不同区域的轮廓使用不同的亮度绘制,相当于设置注水点,有多少个轮廓,就有多少个轮廓
        # 图像上不同线条的灰度值是不同的,底部略暗,越往上灰度越高
        marks = cv.drawContours(marks, contours, index, (index, index, index), 1, 8, hierarchy)

    # 使用分水岭算法
    # 经过watershed函数的处理,不同区域间的值被置为-1(边界)没有标记清楚的区域被置为0,其他每个区域的值保持不变:1,2,...,contours.size()
    marks_water = cv.watershed(img, marks)
    return marks_water


def get_mask_img_(morp_dilate, file_dir):
    contours, hierarchy = cv.findContours(morp_dilate, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    # 32位有符号整数类型,
    marks = np.zeros(morp_dilate.shape[:2], np.int32)
    for index in range(len(contours)):
        dist = cv.pointPolygonTest(contours[index], (marks.shape[0] // 2, marks.shape[1] // 2), True)
        if dist >= 0:
            marks = cv.drawContours(marks, contours, contourIdx=index, color=1, thickness=1, lineType=8,
                                    hierarchy=hierarchy)

    edges = np.zeros((marks.shape[0] + 2, marks.shape[1] + 2), np.uint8)  # 掩码,长短需要加2个像素
    try:
        cv.floodFill(marks, edges, (marks.shape[0] // 2, marks.shape[1] // 2), 1, cv.FLOODFILL_MASK_ONLY)  # 漫水填充
    except Exception as e:
        if file_dir:
            print(file_dir)
            print(e)
            print("=================")
            print(traceback.format_exc())
        # raise e
        marks = np.ones(morp_dilate.shape[:2], np.int32)
    return marks


def get_binary_img(binary_img, mask):
    masked_binary_img = cv.bitwise_and(binary_img, binary_img, mask=mask.astype('uint8'))
    return masked_binary_img


def get_water_img(img, morp_dilate, mask):
    water_img = get_water_img_(img, morp_dilate)
    masked_water = cv.bitwise_and(water_img, water_img, mask=mask.astype('uint8'))
    return masked_water


def get_more_dim(img, file_dir, source_img=None):
    if source_img is None:
        source_img = img
    # img: ndarray: 852, 847, 3
    binary_img = get_binary_img_(img)
    morp_dilate = get_morp_dilate_(binary_img)
    mask = get_mask_img_(morp_dilate, file_dir)

    masked_binary_img = get_binary_img(binary_img, mask)
    masked_water = get_water_img(source_img, morp_dilate, mask)
    # print(f"masked_binary_img shape:{masked_binary_img.shape} masked_water shape:{masked_water.shape}")
    # print(f"type(masked_binary_img):{type(masked_binary_img)} type(masked_water):{type(masked_water)}")
    # return np.stack((masked_binary_img, mask), axis=0)
    return masked_binary_img, masked_water