国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)

這篇具有很好參考價值的文章主要介紹了圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、基本邏輯思路


一、前期圖像處理

1. 讀取圖形、修改尺寸、灰度圖轉(zhuǎn)換

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

2. 直方圖均衡化

原理:

????????直方圖均衡化通常是對圖像灰度值進行歸一化的方法,并且可以增強圖像的對比度;

????????圖像中像素個數(shù)多的灰度級進行展寬,而對圖像中像素個數(shù)少的灰度進行壓縮,從而擴展像原取值的動態(tài)范圍,提高了對比度和灰度色調(diào)的變化,使圖像更加清晰;

????????equalizeHist()函數(shù)中輸入的圖像必須是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("均衡化結(jié)果")
        plt.subplot(2, 2, 4)
        plt.hist(hist_img) #
        plt.title("均衡化結(jié)果直方圖")
        plt.show()
    return hist_img

結(jié)果:

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)

3.?手動濾波:使得圖像整體的明暗變化均衡,直方圖呈現(xiàn)中間多兩邊少的趨勢

邏輯:

  1. 隨機選取5塊小區(qū)域、計算5塊區(qū)域的灰度均值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/7
    dh = int(img.shape[0] / 7)

    # 選取圖像中的5個區(qū)域
    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個區(qū)域的均值
    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個區(qū)域均值的均值
    avg = (avg1 + avg2 + avg3 + avg4 + avg5) / 5

    for 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)是一種典型的非線性濾波技術(shù),基本思想是用像素點鄰域灰度值的中值來代替該像素點的灰度值
    # 2.ksize:核大小,必須是比1大的奇數(shù)【舉個例子: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

結(jié)果:

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)

4. 中值濾波

原理:

中值濾波(Median filter)是一種典型的非線性濾波技術(shù),基本思想是用像素點鄰域灰度值的中值來代替該像素點的灰度值
ksize:核大小,必須是比1大的奇數(shù)【舉個例子:3,5,7…】 ?

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)

代碼:

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("中值濾波結(jié)果")
        plt.subplot(2, 2, 4)
        plt.hist(new_img)
        plt.title("中值濾波結(jié)果直方圖")
        plt.show()
    return new_img

結(jié)果:

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)


二、裂縫延伸

rg = RegionGrow.RegionGrow(img) #創(chuàng)建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 block
        self.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= 9
        return self.imlist

2.?暗度調(diào)節(jié)至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)  # 0
        block_index = 0
        # 遍歷小矩陣列表 (200, 266)
        for block in self.imlist:
            block = np.floor(block / 4)    # 對輸入的多維數(shù)組逐元素進行向下取整:變暗
            block = block.astype(np.uint8)   # 轉(zhuǎn)化為圖像數(shù)據(jù)0-255
            posarr = np.where(block == min_val)  #
            # check is is this block contains min value
            # 如果沒找到就繼續(xù),從下一個小方塊找
            if len(posarr[0]) <= 0:
                self.poslist.append(None)
                block_index += 1
                continue
            # 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 position
            center = (int(self.block_h / 2), int(self.block_w / 2))  # center point
            pt = 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 += 1
        print("min_pos : ",self.poslist)
        return self.poslist

3.延申

? ? ? ? a.? min_pos開始,尋找臨近的黑點,并擴展出一塊完整的區(qū)域:timblock

? ? ? ? b.?每個區(qū)域timblock相加,形成完整的多區(qū)域圖像

    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 seed
            start_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:證明已經(jīng)被延伸到了
                print("已經(jīng)被延伸到了!")
                continue
            # the stack of point which need to be visited
            point_list = [start_point]
            print("point_list:",point_list)
            # the dict of visited point
            visited_point = dict()
            visited_point[start_point] = start_point
            print("visited_point : ",visited_point)
            while len(point_list) > 0:
                # pop the top point and grow around this point
                point = point_list.pop()
                # 延伸?。。?!
                for i in range(-1, 2):
                    for j in range(-1, 2):
                        # the point that is going to grow
                        new_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:
                            continue
                        try:
                            # 如果延伸點在圖像范圍內(nèi)、兩個點的灰度值相差在40之內(nèi):在t imblock將此點賦為255、并將此點放入p oint_list, v isited_point[new_point] = new_point
                            if 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]] = 255
                                point_list.append(new_point)
                                visited_point[new_point] = new_point
                        except:
                            print(new_point)
                # print("point_list:",point_list)
            self.im_merge2(timblock)  #  timblock, self.retimg相加賦給self.retimg
        self.retimg = self.retimg != 0
        # cv2.imshow("retimg",self.retimg)  打印不出來
        return self.retimg

結(jié)果:圖1、圖2分別為兩次延申的timblock,圖3為重疊后的最終結(jié)果

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)


三、裂縫識別(框選)

暫無解析


四、代碼中的其他函數(shù)

1.?連通域標記圖像ConnectedComponents? ?詳解見:?https://blog.csdn.net/jia20003/article/details/80662396

cv.connectedComponents(img)

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)

2.? array尋值(項目中用來尋找黑點、找到的點將以Xarray,Yarray的形式返回,( Xarray[i],Yarray[i] )表示其中的某一點)

圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)

3. 圖像重疊

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

???圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)


五、項目源碼

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 RegionGrow

if __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("識別結(jié)果")
        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 Axes3D


def 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/7
    dh = int(img.shape[0] / 7)

    # 選取圖像中的5個區(qū)域
    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個區(qū)域的均值
    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個區(qū)域均值的均值
    avg = (avg1 + avg2 + avg3 + avg4 + avg5) / 5

    for 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)是一種典型的非線性濾波技術(shù),基本思想是用像素點鄰域灰度值的中值來代替該像素點的灰度值
    # 2.ksize:核大小,必須是比1大的奇數(shù)【舉個例子: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


def 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("均衡化結(jié)果")
        plt.subplot(2, 2, 4)
        plt.hist(hist_img) #
        plt.title("均衡化結(jié)果直方圖")
        plt.show()
    return hist_img


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("中值濾波結(jié)果")
        plt.subplot(2, 2, 4)
        plt.hist(new_img)
        plt.title("中值濾波結(jié)果直方圖")
        plt.show()
    return new_img


def gauss_blur(img, ksize=[3, 3]):
    cv.GaussianBlur(img, ksize=ksize)


def adj_gamma(img, flag=False):
    """
    對圖像進行歸一化處理

    :param img: 輸入圖像
    :param flag: 是否顯示歸一化之后的圖像
    :return: 歸一化之后的圖像
    """
    new_image = img
    new_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_image


def binary_image(img, thresh=0.15, flag=False):
    """
    對圖形進行二值化

    :param img: 輸入圖形
    :param thresh: 閾值
    :param flag: 是否顯示結(jié)果
    :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] / 3
    plt.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_img


def 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??區(qū)域生長實現(xiàn)類

"""
to do image segmentation using region grow method
"""
import numpy as np
import cv2
import DataTool

class RegionGrow:
    def __init__(self, image):
        """
        init class
        :param image: the image need to process
        """
        self.image = image
        self.imlist = []
        self.poslist = []
        self.retimg = np.zeros(shape=self.image.shape)
        self.imh, self.imw = image.shape
        self.block_w = 0
        self.block_h = 0

    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 seed
            start_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:證明已經(jīng)被延伸到了
                print("已經(jīng)被延伸到了!")
                continue
            # the stack of point which need to be visited
            point_list = [start_point]
            print("point_list:",point_list)
            # the dict of visited point
            visited_point = dict()
            visited_point[start_point] = start_point
            print("visited_point : ",visited_point)
            while len(point_list) > 0:
                # pop the top point and grow around this point
                point = point_list.pop()
                # 延伸!?。?!
                for i in range(-1, 2):
                    for j in range(-1, 2):
                        # the point that is going to grow
                        new_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:
                            continue
                        try:
                            # 如果延伸點在圖像范圍內(nèi)、兩個點的灰度值相差在40之內(nèi):在t imblock將此點賦為255、并將此點放入p oint_list, v isited_point[new_point] = new_point
                            if 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]] = 255
                                point_list.append(new_point)
                                visited_point[new_point] = new_point
                        except:
                            print(new_point)
                # print("point_list:",point_list)
            self.im_merge2(timblock)  #  timblock, self.retimg相加賦給self.retimg
        self.retimg = self.retimg != 0
        # cv2.imshow("retimg",self.retimg)  打印不出來
        return self.retimg


    def img_cut(self):
        """
        cut the image into 9 parts
        :return: list of image
        """
        # determine the size of pre block
        self.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= 9
        return self.imlist


    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)  # 0
        block_index = 0
        # 遍歷小矩陣列表 (200, 266)
        for block in self.imlist:
            block = np.floor(block / 4)    # 對輸入的多維數(shù)組逐元素進行向下取整:變暗
            block = block.astype(np.uint8)   # 轉(zhuǎn)化為圖像數(shù)據(jù)0-255
            posarr = np.where(block == min_val)  #
            # check is is this block contains min value
            # 如果沒找到就繼續(xù),從下一個小方塊找
            if len(posarr[0]) <= 0:
                self.poslist.append(None)
                block_index += 1
                continue
            # 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 position
            center = (int(self.block_h / 2), int(self.block_w / 2))  # center point
            pt = 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 += 1
        print("min_pos : ",self.poslist)
        return self.poslist

    def 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 math


def 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 distance
    for 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? 實現(xiàn)區(qū)域框選文章來源地址http://www.zghlxwxcb.cn/news/detail-408731.html

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


def get_area_pos(img, filter_size=1000, flag=False):
    """
    從圖形中獲取區(qū)域面積及位置

    :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 = []
    # 統(tǒng)計面積以及位置
    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_list


def connected_region_label(img, flag=False):
    """
    對二值圖像進行連通性分析

    :param img: 輸入圖像
    :param flag: 是否顯示結(jié)果
    :return: 連通區(qū)域總數(shù),標記的每個連通區(qū)域
    """

    img = img.astype(np.uint8)
    result, labels = cv.connectedComponents(img)
    if flag:
        temp = labels * 10
        plt.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_imgs

def find_min_max_width(contour):
    min_dict = dict()
    max_dict = dict()
    max_width = 0
    min_width = 999
    min_pos = 0
    max_pos = 0
    for 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_width


def find_min_max_width_vertical(contour):
    min_dict = dict()
    max_dict = dict()
    max_width = 0
    min_width = 999
    min_pos = 0
    max_pos = 0
    for 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

到了這里,關(guān)于圖像處理(二)之 基于OpenCV的水泥裂縫檢測(區(qū)域延申)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包