一、基本逻辑思路


一、前期图像处理

1. 读取图形、修改尺寸、灰度图转换

    # 读取图片origin = PreProcess.read_image("test_img/1.jpg", color_code=cv.IMREAD_ANYCOLOR) # 裁剪图片origin = PreProcess.resize_img(origin)# 彩色图片->灰度图img = PreProcess.convert_color(origin)

2. 直方图均衡化

原理:

        直方图均衡化通常是对图像灰度值进行归一化的方法,并且可以增强图像的对比度;

        图像中像素个数多的灰度级进行展宽,而对图像中像素个数少的灰度进行压缩,从而扩展像原取值的动态范围,提高了对比度和灰度色调的变化,使图像更加清晰;

        equalizeHist()函数中输入的图像必须是8-bit的单通道图像。

代码:

img = PreProcess.equalize_hist(img, flag=False)   # 均值化
def equalize_hist(img, flag=False):hist_img = np.zeros(shape=img.shape)hist_img = cv.equalizeHist(img, hist_img)if flag:plt.rcParams['font.sans-serif'] = ['SimHei']   # 正确打印中文plt.subplot(2, 2, 1)plt.imshow(img, cmap="gray")plt.title("原图")plt.subplot(2, 2, 2)plt.hist(img)  #plt.title("原图直方图")plt.subplot(2, 2, 3)plt.imshow(hist_img, cmap="gray")  #plt.title("均衡化结果")plt.subplot(2, 2, 4)plt.hist(hist_img) #plt.title("均衡化结果直方图")plt.show()return hist_img

结果:

3. 手动滤波:使得图像整体的明暗变化均衡,直方图呈现中间多两边少的趋势

逻辑:

  1. 随机选取5块小区域、计算5块区域的灰度均值avg
  2. 图片按照10*10的小矩阵Matrix遍历修改:
    1. 计算Matrix的均值Mavg
    2. Matrix = Matrix*avg/Mavg

代码:

img = PreProcess.center_avg_imp(img, ksize=20, flag=False)
def center_avg_imp(img, ksize=10, flag=False):new_img = np.copy(img)dw = int(img.shape[1] / 7)   # 获取原图像长宽的1/7dh = int(img.shape[0] / 7)# 选取图像中的5个区域region_1 = new_img[dh * 1: dh * 2, dw * 1: dw * 2]region_2 = new_img[dh * 1: dh * 2, dw * 5: dw * 6]region_3 = new_img[dh * 5: dh * 6, dw * 5: dw * 6]region_4 = new_img[dh * 1: dh * 2, dw * 5: dw * 6]region_5 = new_img[dh * 3: dh * 4, dw * 3: dw * 4]# 计算5个区域的均值avg1 = np.average(region_1)avg2 = np.average(region_2)avg3 = np.average(region_3)avg4 = np.average(region_4)avg5 = np.average(region_5)# 5个区域均值的均值avg = (avg1 + avg2 + avg3 + avg4 + avg5) / 5for x in range(0, img.shape[0], ksize):for y in range(0, img.shape[1], ksize):# 每次运算选取10*10的像素方块进行操作    *均值/方块均值new_img[x:x + ksize, y:y + ksize] = \img[x:x + ksize, y:y + ksize] * (avg / np.average(img[x:x + ksize, y:y + ksize]))# new_img = cv.medianBlur(img, 15)# 中值滤波(Median filter)是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值# 2.ksize:核大小,必须是比1大的奇数【举个例子:3,5,7…】if flag:plt.subplot(2, 2, 1)plt.imshow(img, cmap='gray')plt.subplot(2, 2, 2)plt.imshow(new_img, cmap='gray')plt.subplot(2, 2, 4)plt.hist(new_img)plt.subplot(2, 2, 3)plt.hist(img)plt.show()return new_img

结果:

4. 中值滤波

原理:

中值滤波(Median filter)是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值
ksize:核大小,必须是比1大的奇数【举个例子:3,5,7…】  

代码:

img = PreProcess.med_blur(img, ksize=5, flag=False)
def med_blur(img, ksize=3, flag=False):"""Median filter for input image:param img: input image:param ksize: size of filter:return: image after median filter"""if img.dtype is not np.uint8:img = img.astype(np.uint8)new_img = cv.medianBlur(img, ksize)if flag:plt.rcParams['font.sans-serif'] = ['SimHei']  # 正确打印中文plt.subplot(2, 2, 1)plt.imshow(img, cmap="gray")plt.title("原图")plt.subplot(2, 2, 2)plt.hist(img)plt.title("原图直方图")plt.subplot(2, 2, 3)plt.imshow(new_img, cmap="gray")plt.title("中值滤波结果")plt.subplot(2, 2, 4)plt.hist(new_img)plt.title("中值滤波结果直方图")plt.show()return new_img

结果:


二、裂缝延伸

rg = RegionGrow.RegionGrow(img) #创建RegionGrow类实例 ,完整代码见博客最后面
rg.img_cut()
rg.min_pos()
img = rg.region_grow()  # 延伸

1.  将原图像切割成3*3小矩阵

    def img_cut(self):"""cut the image into 9 parts:return: list of image"""# determine the size of pre blockself.block_w = int(self.imw / 3)self.block_h = int(self.imh / 3)for i in range(3):for j in range(3):# 以3*3小矩形进行遍历self.imlist.append(self.image[i * self.block_h:(i + 1) * self.block_h,j * self.block_w:(j + 1) * self.block_w])#返回矩阵列表len= 9return self.imlist

2. 暗度调节至1/4,寻找小矩阵图像中距离中心点最暗的点(黑点)

min_pos :  [(188, 138), None, None, (214, 183), (290, 388), (337, 681), None, (479, 342), None

    def min_pos(self):"""to find out the darkness point in each block:return: a list of position in each block"""min_val = np.min(np.min(self.image))print("min_val",min_val)  # 0block_index = 0# 遍历小矩阵列表 (200, 266)for block in self.imlist:block = np.floor(block / 4)    # 对输入的多维数组逐元素进行向下取整:变暗block = block.astype(np.uint8)   # 转化为图像数据0-255posarr = np.where(block == min_val)  ## check is is this block contains min value# 如果没找到就继续,从下一个小方块找if len(posarr[0]) <= 0:self.poslist.append(None)block_index += 1continue# todo using a more useful method to chose the seed# No.1 chose the point which is closest to center point# pick a point randomly and convert to global positioncenter = (int(self.block_h / 2), int(self.block_w / 2))  # center pointpt = DataTool.min_distace(posarr, center)  # 在posarr中找距离center最近的坐标posw = int(block_index % 3) * self.block_w + pt[1]posh = int(block_index / 3) * self.block_h + pt[0]# posw,posh为 posarr_min 在大图中的绝对坐标self.poslist.append((posh, posw))block_index += 1print("min_pos : ",self.poslist)return self.poslist

3.延申

a.  min_pos开始,寻找临近的黑点,并扩展出一块完整的区域:timblock

b. 每个区域timblock相加,形成完整的多区域图像

    def region_grow(self, mode=8):"""image segmentation using region grow:type img: image:param img: input image:type mode: int:param mode: 4 or 8 only(8 as default):return: new image after segmentation"""for x in range(9):point = self.poslist[x]timblock = np.zeros(shape=self.image.shape)if point is None:print("原图没有黑点!")continue# the position of the seedstart_point = (point[0], point[1])   # 从距离中心点最近的黑像素点开始# print("retimg:",np.where(self.retimg > 0))cv2.imshow("11 ",self.retimg)cv2.waitKey()if self.retimg[start_point[0], start_point[1]] != 0:# 如果此点的像素不为0:证明已经被延伸到了print("已经被延伸到了!")continue# the stack of point which need to be visitedpoint_list = [start_point]print("point_list:",point_list)# the dict of visited pointvisited_point = dict()visited_point[start_point] = start_pointprint("visited_point : ",visited_point)while len(point_list) > 0:# pop the top point and grow around this pointpoint = point_list.pop()# 延伸!!!!for i in range(-1, 2):for j in range(-1, 2):# the point that is going to grownew_point = point[0] + i, point[1] + j# is the point visited, if visited pass the point# print("延伸后的点:",new_point)if visited_point.get(new_point) is not None:continuetry:# 如果延伸点在图像范围内、两个点的灰度值相差在40之内:在t imblock将此点赋为255、并将此点放入p oint_list, v isited_point[new_point] = new_pointif 0 <= new_point[0] < self.imh and 0 <= new_point[1] < self.imw and np.abs(int(self.image[new_point[0], new_point[1]]) -int(self.image[start_point[0], start_point[1]])) < 40:timblock[new_point[0], new_point[1]] = 255point_list.append(new_point)visited_point[new_point] = new_pointexcept:print(new_point)# print("point_list:",point_list)self.im_merge2(timblock)  #  timblock, self.retimg相加赋给self.retimgself.retimg = self.retimg != 0# cv2.imshow("retimg",self.retimg)  打印不出来return self.retimg

结果:图1、图2分别为两次延申的timblock,图3为重叠后的最终结果


三、裂缝识别(框选)

暂无解析


四、代码中的其他函数

1. 连通域标记图像ConnectedComponents   详解见: https://blog.csdn.net/jia20003/article/details/80662396

cv.connectedComponents(img)

2.  array寻值(项目中用来寻找黑点、找到的点将以Xarray,Yarray的形式返回,( Xarray[i],Yarray[i] )表示其中的某一点)

3. 图像重叠

self.retimg = np.add(temp_img, self.retimg)


五、项目源码

1. main.py

# coding:utf-8
import time
import cv2 as cv
from matplotlib import pyplot as plt
import numpy as np
import Feature
import PreProcess
import RegionGrowif __name__ == "__main__":# 读取图片origin = PreProcess.read_image("test_img/1.jpg", color_code=cv.IMREAD_ANYCOLOR)   # 彩色图片# 裁剪图片origin = PreProcess.resize_img(origin)# 彩色图片->灰度图img = PreProcess.convert_color(origin)if img is not None:img = PreProcess.equalize_hist(img, flag=False)   # 均值化# cv.imshow("equalize_hist",img)img = PreProcess.center_avg_imp(img, ksize=20, flag=False)# cv.imshow("center_avg_imp2", img)img = PreProcess.med_blur(img, ksize=5, flag=False)start_time = time.time()print(start_time)rg = RegionGrow.RegionGrow(img)rg.img_cut()rg.min_pos()img = rg.region_grow()  # 衍生!!end_time = time.time()print("run in %.2f" % (end_time - start_time))# img = rg.im_merge()plt.imshow(img, cmap="gray")plt.show()# img = PreProcess.binary_image(img, 100, True)img = PreProcess.med_blur(img, ksize=3, flag=False)   # 中值滤波plt.imsave("a.jpg", img, cmap='gray')# img = cv.dilate(img, np.array([[1,1,1],[1,1,1],[1,1,1]]))result, imgs = Feature.connected_region_label(img, flag=True)# plt.imshow(imgs)plt.imshow(imgs[0])plt.imshow(imgs[1])plt.imshow(imgs[2])print(result,imgs[0].shape,imgs[1].shape,imgs[2].shape)for img in imgs[1:]:area_result = Feature.get_area_pos(img, flag=False)print(area_result)for r in area_result:origin = cv.rectangle(origin,(r[1], r[2]),(r[1] + r[3], r[2] + r[4]),(0, 0, 0),thickness=2)origin = cv.putText(origin,'area:' + str(r[0]),color=(0, 0, 255),org=(r[1], r[2] + 30),fontFace=cv.FONT_ITALIC,fontScale=0.5)origin = PreProcess.convert_color(origin, cv.COLOR_BGR2RGB)plt.imshow(origin)plt.rcParams['font.sans-serif'] = ['KaiTi']plt.title("识别结果")plt.show()plt.imsave("b.jpg", origin)

2. PreProcess.py 前期图像处理

import cv2 as cv
import numpy as np
from matplotlib import cm
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3Ddef read_image(path, color_code=cv.IMREAD_GRAYSCALE):"""read a picture from path:type path: string:param path: the location of a picture:type color_code: opencv color code:param color_code: which type the image should be read, cv.IMREAD_GRAYSCALE as default:return: the picture read from the path, None if there is an error"""return cv.imread(path, color_code)def convert_color_gray(image):"""convert a bgr image to gray:type image: opencv image:param image: the image need to convert:return: an image in gray color"""return cv.cvtColor(image, cv.COLOR_BGR2GRAY)def resize_img(img, width=800):"""resize image:type img: image:param img: input image:type width: int:param width: width after resize,800 as default:return: image after resize"""return cv.resize(img, (width, int(width * img.shape[0] / img.shape[1])))def convert_color(image, code=cv.COLOR_BGR2GRAY):"""convert color space of an image:type image: image:param image: input image:type code: opencv convert code:param code: opencv color convert , COLOR_BGR2GRAY as default:return: image after convert"""return cv.cvtColor(image, code)def center_avg_imp(img, ksize=10, flag=False):"""improve the image pixels by image center pixel average:type img: image:param img: the image need to be improved:type ksize: int:param ksize: the filter size, 10 as default:type flag: Boolean:param flag: show the result or not:return: the result after deal"""new_img = np.copy(img)dw = int(img.shape[1] / 7)   # 获取原图像长宽的1/7dh = int(img.shape[0] / 7)# 选取图像中的5个区域region_1 = new_img[dh * 1: dh * 2, dw * 1: dw * 2]region_2 = new_img[dh * 1: dh * 2, dw * 5: dw * 6]region_3 = new_img[dh * 5: dh * 6, dw * 5: dw * 6]region_4 = new_img[dh * 1: dh * 2, dw * 5: dw * 6]region_5 = new_img[dh * 3: dh * 4, dw * 3: dw * 4]# 计算5个区域的均值avg1 = np.average(region_1)avg2 = np.average(region_2)avg3 = np.average(region_3)avg4 = np.average(region_4)avg5 = np.average(region_5)# 5个区域均值的均值avg = (avg1 + avg2 + avg3 + avg4 + avg5) / 5for x in range(0, img.shape[0], ksize):for y in range(0, img.shape[1], ksize):# 每次运算选取10*10的像素方块进行操作    *均值/方块均值new_img[x:x + ksize, y:y + ksize] = \img[x:x + ksize, y:y + ksize] * (avg / np.average(img[x:x + ksize, y:y + ksize]))# new_img = cv.medianBlur(img, 15)# 中值滤波(Median filter)是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值# 2.ksize:核大小,必须是比1大的奇数【举个例子:3,5,7…】if flag:plt.subplot(2, 2, 1)plt.imshow(img, cmap='gray')plt.subplot(2, 2, 2)plt.imshow(new_img, cmap='gray')plt.subplot(2, 2, 4)plt.hist(new_img)plt.subplot(2, 2, 3)plt.hist(img)plt.show()return new_imgdef equalize_hist(img, flag=False):"""equalize hist to improve image:type img: image:param img: input image:type flag: Boolean:param flag: show the result if is True, False as default:return: the image after equalize hist"""hist_img = np.zeros(shape=img.shape)hist_img = cv.equalizeHist(img, hist_img)if flag:plt.rcParams['font.sans-serif'] = ['SimHei']   # 正确打印中文plt.subplot(2, 2, 1)plt.imshow(img, cmap="gray")plt.title("原图")plt.subplot(2, 2, 2)plt.hist(img)  #plt.title("原图直方图")plt.subplot(2, 2, 3)plt.imshow(hist_img, cmap="gray")  #plt.title("均衡化结果")plt.subplot(2, 2, 4)plt.hist(hist_img) #plt.title("均衡化结果直方图")plt.show()return hist_imgdef med_blur(img, ksize=3, flag=False):"""Median filter for input image:param img: input image:param ksize: size of filter:return: image after median filter"""if img.dtype is not np.uint8:img = img.astype(np.uint8)new_img = cv.medianBlur(img, ksize)if flag:plt.rcParams['font.sans-serif'] = ['SimHei']  # 正确打印中文plt.subplot(2, 2, 1)plt.imshow(img, cmap="gray")plt.title("原图")plt.subplot(2, 2, 2)plt.hist(img)plt.title("原图直方图")plt.subplot(2, 2, 3)plt.imshow(new_img, cmap="gray")plt.title("中值滤波结果")plt.subplot(2, 2, 4)plt.hist(new_img)plt.title("中值滤波结果直方图")plt.show()return new_imgdef gauss_blur(img, ksize=[3, 3]):cv.GaussianBlur(img, ksize=ksize)def adj_gamma(img, flag=False):"""对图像进行归一化处理:param img: 输入图像:param flag: 是否显示归一化之后的图像:return: 归一化之后的图像"""new_image = imgnew_image = new_image - np.min(np.min(new_image))new_image = new_image / np.max(np.max(new_image))if flag:x = np.arange(0, new_image.shape[1], 1)y = np.arange(0, new_image.shape[0], 1)xg, yg = np.meshgrid(x, y)fig = plt.figure()ax = Axes3D(fig)ax.plot_surface(xg, yg, new_image, rstride=1, cstride=1, cmap=cm.viridis)plt.show()return new_imagedef binary_image(img, thresh=0.15, flag=False):"""对图形进行二值化:param img: 输入图形:param thresh: 阈值:param flag: 是否显示结果:return: 二值化之后的图形"""t = np.reshape(img, img.shape[1] * img.shape[0])pixel = np.bincount(t)xdata = np.linspace(1, pixel.shape[0], pixel.shape[0])index = np.argwhere(pixel == np.max(pixel))thresh = index[0][0] / 3plt.plot(pixel)plt.show()ret, new_img = cv.threshold(img, thresh, 255, cv.THRESH_BINARY)new_img = np.abs(new_img - 255)if flag:plt.subplot(2, 1, 1)plt.imshow(img, cmap="gray")plt.subplot(2, 1, 2)plt.imshow(new_img, cmap="gray")plt.show()return new_imgdef hist_segmentation(img):"""do image segmentation using hist:type img: gray image:param img: origin image:return: image after segmentation"""hist = cv.calcHist([img], [0], None, [256], [0, 255])max_index = np.where(hist == max(hist))mask = hist[0:max_index[0][0]]min_index = np.where(mask == min(mask))ret, new_im = cv.threshold(img, min_index[0][0], 255, cv.THRESH_BINARY)return new_im

3. RegionGrow.py  区域生长实现类

"""
to do image segmentation using region grow method
"""
import numpy as np
import cv2
import DataToolclass RegionGrow:def __init__(self, image):"""init class:param image: the image need to process"""self.image = imageself.imlist = []self.poslist = []self.retimg = np.zeros(shape=self.image.shape)self.imh, self.imw = image.shapeself.block_w = 0self.block_h = 0def region_grow(self, mode=8):"""image segmentation using region grow:type img: image:param img: input image:type mode: int:param mode: 4 or 8 only(8 as default):return: new image after segmentation"""for x in range(9):point = self.poslist[x]timblock = np.zeros(shape=self.image.shape)if point is None:print("原图没有黑点!")continue# the position of the seedstart_point = (point[0], point[1])   # 从距离中心点最近的黑像素点开始# print("retimg:",np.where(self.retimg > 0))cv2.imshow("11 ",self.retimg)cv2.waitKey()if self.retimg[start_point[0], start_point[1]] != 0:# 如果此点的像素不为0:证明已经被延伸到了print("已经被延伸到了!")continue# the stack of point which need to be visitedpoint_list = [start_point]print("point_list:",point_list)# the dict of visited pointvisited_point = dict()visited_point[start_point] = start_pointprint("visited_point : ",visited_point)while len(point_list) > 0:# pop the top point and grow around this pointpoint = point_list.pop()# 延伸!!!!for i in range(-1, 2):for j in range(-1, 2):# the point that is going to grownew_point = point[0] + i, point[1] + j# is the point visited, if visited pass the point# print("延伸后的点:",new_point)if visited_point.get(new_point) is not None:continuetry:# 如果延伸点在图像范围内、两个点的灰度值相差在40之内:在t imblock将此点赋为255、并将此点放入p oint_list, v isited_point[new_point] = new_pointif 0 <= new_point[0] < self.imh and 0 <= new_point[1] < self.imw and np.abs(int(self.image[new_point[0], new_point[1]]) -int(self.image[start_point[0], start_point[1]])) < 40:timblock[new_point[0], new_point[1]] = 255point_list.append(new_point)visited_point[new_point] = new_pointexcept:print(new_point)# print("point_list:",point_list)self.im_merge2(timblock)  #  timblock, self.retimg相加赋给self.retimgself.retimg = self.retimg != 0# cv2.imshow("retimg",self.retimg)  打印不出来return self.retimgdef img_cut(self):"""cut the image into 9 parts:return: list of image"""# determine the size of pre blockself.block_w = int(self.imw / 3)self.block_h = int(self.imh / 3)for i in range(3):for j in range(3):# 以3*3小矩形进行遍历self.imlist.append(self.image[i * self.block_h:(i + 1) * self.block_h,j * self.block_w:(j + 1) * self.block_w])#返回矩阵列表len= 9return self.imlistdef min_pos(self):"""to find out the darkness point in each block:return: a list of position in each block"""min_val = np.min(np.min(self.image))print("min_val",min_val)  # 0block_index = 0# 遍历小矩阵列表 (200, 266)for block in self.imlist:block = np.floor(block / 4)    # 对输入的多维数组逐元素进行向下取整:变暗block = block.astype(np.uint8)   # 转化为图像数据0-255posarr = np.where(block == min_val)  ## check is is this block contains min value# 如果没找到就继续,从下一个小方块找if len(posarr[0]) <= 0:self.poslist.append(None)block_index += 1continue# todo using a more useful method to chose the seed# No.1 chose the point which is closest to center point# pick a point randomly and convert to global positioncenter = (int(self.block_h / 2), int(self.block_w / 2))  # center pointpt = DataTool.min_distace(posarr, center)  # 在posarr中找距离center最近的坐标posw = int(block_index % 3) * self.block_w + pt[1]posh = int(block_index / 3) * self.block_h + pt[0]# posw,posh为 posarr_min 在大图中的绝对坐标self.poslist.append((posh, posw))block_index += 1print("min_pos : ",self.poslist)return self.poslistdef im_merge2(self, temp_img):self.retimg = np.add(temp_img, self.retimg)print('im_merge2:',temp_img)cv2.imshow("im_merge2",temp_img)cv2.waitKey()

4. DataTool.py  工具脚本

import mathdef distance_calc(point1, point2):"""to calculate the distance of 2 points:param point1: pt1:param point2: pt2:return: the distance"""return math.sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2)def min_distace(pointlist, center):"""given a group of points and a center point to find out the point which is closest to center point:type pointlist: tuple:param pointlist: the list of point:type center: tuple:param center: center point:return: the point closest to center"""dis_dict = dict()dis_list = []# for all the point calculate distancefor index in range(len(pointlist[0])):pt = (pointlist[0][index], pointlist[1][index])dis = distance_calc(pt, center)dis_dict[dis] = pt    # 距离:pointlist坐标dis_list.append(dis)dis_list.sort()return dis_dict[dis_list[0]]   # 在pointlist中找距离center最近的坐标

5. Feature.py  实现区域框选

import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltdef get_area_pos(img, filter_size=1000, flag=False):"""从图形中获取区域面积及位置:param img: 输入图形:param filter_size: 过滤的面积大小:param flag: show result?:return: list(area,pos);area:int, pos(x,y,w,h)"""# 检查类型if img.dtype is not np.uint8:img = img.astype(np.uint8)# 获取边缘点contours, hierarchy = cv.findContours(img,cv.RETR_TREE,cv.CHAIN_APPROX_NONE)result_list = []# 统计面积以及位置for con in contours:image = cv.drawContours(img, con, -1, 255)area = cv.contourArea(con)if area > filter_size:x, y, w, h = cv.boundingRect(con)result_list.append((area, x, y, w, h))if w / h > 1:print("横向裂缝")print(find_min_max_width(con))else:print("纵向裂缝")print(find_min_max_width_vertical(con))if flag:temp_img = np.zeros(image.shape)temp_img = cv.drawContours(temp_img, con, -1, 255)print('x:%d,y:%d,w:%d,h:%d' % (x, y, w, h))temp_img = cv.rectangle(temp_img, (x, y), (x + w, y + h), 180)cv.imshow("result", temp_img)cv.waitKey()return result_listdef connected_region_label(img, flag=False):"""对二值图像进行连通性分析:param img: 输入图像:param flag: 是否显示结果:return: 连通区域总数,标记的每个连通区域"""img = img.astype(np.uint8)result, labels = cv.connectedComponents(img)if flag:temp = labels * 10plt.imshow(temp, cmap="gray")plt.show()print(result)labels_imgs = []for i in range(result):ret = np.asarray((labels == i), np.bool)labels_imgs.append(ret)return result, labels_imgsdef find_min_max_width(contour):min_dict = dict()max_dict = dict()max_width = 0min_width = 999min_pos = 0max_pos = 0for pt in contour:if min_dict.get(pt[0][0]) is None or max_dict.get(pt[0][0]) is None:min_dict[pt[0][0]] = max_dict[pt[0][0]] = pt[0][1]elif min_dict[pt[0][0]] > pt[0][1]:min_dict[pt[0][0]] = pt[0][1]if max_width < (max_dict[pt[0][0]] - min_dict[pt[0][0]]):max_width = max_dict[pt[0][0]] - min_dict[pt[0][0]]max_pos = pt[0][0]if min_width > (max_dict[pt[0][0]] - min_dict[pt[0][0]]):min_width = max_dict[pt[0][0]] - min_dict[pt[0][0]]min_pos = pt[0][0]elif max_dict[pt[0][0]] < pt[0][1]:max_dict[pt[0][0]] = pt[0][1]if max_width < (max_dict[pt[0][0]] - min_dict[pt[0][0]]):max_width = max_dict[pt[0][0]] - min_dict[pt[0][0]]max_pos = pt[0][0]if min_width > (max_dict[pt[0][0]] - min_dict[pt[0][0]]):min_width = max_dict[pt[0][0]] - min_dict[pt[0][0]]min_pos = pt[0][0]return max_width, min_widthdef find_min_max_width_vertical(contour):min_dict = dict()max_dict = dict()max_width = 0min_width = 999min_pos = 0max_pos = 0for pt in contour:if min_dict.get(pt[0][1]) is None or max_dict.get(pt[0][1]) is None:min_dict[pt[0][1]] = max_dict[pt[0][1]] = pt[0][0]elif min_dict[pt[0][1]] > pt[0][0]:min_dict[pt[0][1]] = pt[0][0]if max_width < (max_dict[pt[0][1]] - min_dict[pt[0][1]]):max_width = max_dict[pt[0][1]] - min_dict[pt[0][1]]max_pos = pt[0][0]if min_width > (max_dict[pt[0][1]] - min_dict[pt[0][1]]):min_width = max_dict[pt[0][1]] - min_dict[pt[0][1]]min_pos = pt[0][0]elif max_dict[pt[0][1]] < pt[0][0]:max_dict[pt[0][1]] = pt[0][0]if max_width < (max_dict[pt[0][1]] - min_dict[pt[0][1]]):max_width = max_dict[pt[0][1]] - min_dict[pt[0][1]]max_pos = pt[0][0]if min_width > (max_dict[pt[0][1]] - min_dict[pt[0][1]]):min_width = max_dict[pt[0][1]] - min_dict[pt[0][1]]min_pos = pt[0][0]return max_width, min_width

图像处理(二)之 基于OpenCV的水泥裂缝检测(区域延申)相关推荐

  1. [Python图像处理] 二十八.OpenCV快速实现人脸检测及视频中的人脸

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  2. 运用特征脸方法的基于Opencv的猫脸检测实现

    本文禁止转载.抄袭,请尊重作者权利. 使用特征脸方法的基于Opencv的猫脸检测实现 摘要 目前,在计算机视觉和模式识别领域,脸识别技术是一个很活跃的课题,人脸识别的方法已经十分丰富,而对于日常生活中 ...

  3. 基于机器视觉的路面裂缝检测方法研究与实现

    基于MATLAB的路面裂缝检测系统[过程图,源码] 课题背景 裂缝是最常见的路面损坏,可能会危及公路和高速公路的安全.在路面裂缝变的更糟糕之前及时进行修补,可以大大节省路面维修的资金.路面裂缝是评估道 ...

  4. 基于半交互式的裂缝检测方法

    裂缝的危害已深入经济社会发展的各个领域,比如交通运输领域中的公路路面裂缝,高速公路隧道壁裂缝等:工业产品领域中的光学玻璃裂缝,木材表面裂缝等等:其安全性检测直接关系到经济发展和安全等重大问题.裂缝虽然 ...

  5. Python基于OpenCV的实时疲劳检测[源码&演示视频&部署教程]

    1.图片演示 2.视频演示 [项目分享]Python基于OpenCV的实时疲劳检测[源码&演示视频&部署教程]_哔哩哔哩_bilibili 3.检测方法 1)方法 与用于计算眨眼的传统 ...

  6. 基于Opencv的车距检测系统(源码&教程)

    1.研究背景 对本车前方车辆的识别及距离检测是计算机视觉技术在智能网联汽车中的一个重要内容.要想在错综繁杂的交通环境中实现无人驾驶,对行车环境中其他车辆信息的获取是十分重要的.因此,对本车前方车辆的识 ...

  7. 基于OpenCV的混凝土裂纹检测

    基于OpenCV的混凝土裂纹检测 前言 这是我发的第一次博客,有什么建议大家可以给我留言,感激不尽! 接下来,我们进入正题. 一.使用函数库 numpy, opencv, heapq, skimage ...

  8. Python基于OpenCV的异常行为检测系统[源码&部署教程]

    1.项目背景 智能视频监控(Intelligent Video Surveillance , IVS)[1.2·3.4是计算机视觉技术5l在安防领域的应用,实现了由"被动监控"到& ...

  9. RIKIBOT使用系列-基于Opencv HSV的色块检测

    目录 一. 简介 二.查找色值 1.摄像头的角度调 2.启动检测与查找 三. 验证HSV色值 1.写入色值到文件 2.启动检测 四.交流方式 一. 简介 这里学习一下如何用摄像头检测HSV色值,Ope ...

最新文章

  1. Linux系统监测-命令集
  2. 模拟浏览器的神器 - HtmlUnit
  3. 我的工作流为什么启动不了
  4. 重构改善既有代码的设计(笔记)
  5. CSS实现垂直居中的5种方法
  6. RESTful Web服务可发现性,第4部分
  7. Jmeter BeanShell采样器提取接口响应并传递(三)
  8. php 操作mysql 分表的一种方法
  9. IE6 透明遮挡falsh解决方案
  10. WF3设计时性能II
  11. unity和python哪个好学_纠结学习Python还是unity3d_课课家教育
  12. 欧拉角Yaw、Pitch、Roll
  13. Markdown的下载和操作介绍
  14. PHP实现图片转字符画
  15. 通过SCDM导入CAD几何模型到Icepak_51CAE_新浪博客
  16. 计算机网络电子邮件的基本格式,怎样的格式才是正确的电子邮件格式?
  17. SylixOS -- 网卡驱动浅析
  18. 这里有美女!!!!抖音上很火的3D立体动态相册的实现(纯CSS)
  19. Guava限流器RateLimiter
  20. 任正非告别荣耀讲话—-陌生的感动

热门文章

  1. JQuery 类似Vue.js的双向数据绑定器。
  2. 畅言评论的版权及样式如何修改CSS一步简单搞定
  3. JQuery ajax提交表单及表单验证
  4. 爬虫日记-模拟登录cookie操作
  5. war3 兵种出生位置研究
  6. java工厂方法模式_java-工厂方法模式的优势
  7. mysql下载好压缩包如何安装_Mysql下载压缩包安装及Navicat连接
  8. gradle-7.2-all 百度网盘下载
  9. 【硬件】墨水屏显示改造方案
  10. T45 LaTex特殊符号