【Python】时间测试装饰器问题解决记录

问题

昨天在对04年的一篇分割论文进行实现测试,封装测试时间装饰器的时候,发现主逻辑运行结束后,装饰器那边的时间 log 打印了居多遍。

分析

  • 底层原因?因为对装饰器还不太熟,怀疑程序是不是运行太久,这个任务重入了,调研一番后发现没这个机制
  • 导包的原因?因为贪图方便,在导包的时候直接把改流程写在函数内部

解决

把 import time 从函数内部调整到全局,问题解决。
在这里插入图片描述

小结

可能是实现的问题,相比较于 C++ 的实现,Python 真的是慢了很多很多…

代码

import cv2
import sys
import time
import numpy as np


def diff(img, x1, y1, x2, y2):
    r = np.square(img[0][y1, x1] - img[0][y2, x2])
    g = np.square(img[1][y1, x1] - img[1][y2, x2])
    b = np.square(img[2][y1, x1] - img[2][y2, x2])
    return np.sqrt(r + b + g)


class universe():
    def __init__(self, elements):
        self.num = elements;
        self.elts = []
        for i in range(elements):
            rank = 0;
            size = 1;
            p = i;
            self.elts.append((rank, size, p))

    # a older func
    # def find(self, x):
    #     y = x
    #     while (y != self.elts[y][2]):
    #         y = self.elts[y][2]
    #     self.elts[x] = (self.elts[x][0], self.elts[x][1], y);
    #     return y

    # a newer func use recursion
    def find(self, u):
        if self.elts[u][2] == u:
            return u

        self.elts[u] = (self.elts[u][0], self.elts[u][1], self.find(self.elts[u][2]))
        return self.elts[u][2]

    def join(self, x, y):
        if self.elts[x][0] > self.elts[y][0]:
            self.elts[y] = (self.elts[y][0], self.elts[y][1], self.elts[x][2]);
            self.elts[x] = (self.elts[x][0], self.elts[x][1] + self.elts[y][1], self.elts[x][2])
        else:
            self.elts[x] = (self.elts[x][0], self.elts[x][1], self.elts[y][2])
            self.elts[y] = (self.elts[y][0], self.elts[y][1] + self.elts[x][1], self.elts[y][2])
            if self.elts[x][0] == self.elts[y][0]:
                self.elts[y] = (self.elts[y][0] + 1, self.elts[y][1], self.elts[y][2])
        self.num -= 1

    def size(self, x):
        return self.elts[x][1]

    def num_sets(self):
        return self.num


def THRESHOLD(size, c):
    return c / size

# Segment a graph
#
# Returns a disjoint-set forest representing the segmentation.
#
# num_vertices: number of vertices in graph.
# num_edges: number of edges in graph
# edges: array of edges.
# c: constant for treshold function.
def segment_graph(num_vertices, num_edges, graph, c):
    # make a disjoint-set forest
    u = universe(num_vertices)

    # init thresholds
    threshold = np.zeros(num_vertices, dtype=float)
    for i in range(num_vertices):
        threshold[i] = THRESHOLD(1, c)

    # for each edge, in non-decreasing weight order...
    for i in range(num_edges):
        a = u.find(graph[i][0])
        b = u.find(graph[i][1])
        if a != b:
            if ((graph[i][2] <= threshold[a]) and
                    graph[i][2] <= threshold[b]):
                u.join(a, b)
                a = u.find(a)
                threshold[a] = graph[i][2] + THRESHOLD(u.size(a), c)
    return u


def random_rgb():
    r = np.random.rand() * 255
    g = np.random.rand() * 255
    b = np.random.rand() * 255
    return (r, g, b)

# Segment an image
#
# Returns a color image representing the segmentation.
#
# im: image to segment.
# sigma: to smooth the image.
# c: constant for treshold function.
# min_size: minimum component size (enforced by post-processing stage).
# num_ccs: number of connected components in the segmentation.

def segment_image(im, sigma, c,
                  min_size, num_ccs):
    height, width, channel = im.shape
    print(height, width, channel)
    im = np.array(im, dtype=float)
    gaussian_img = cv2.GaussianBlur(im, (5, 5), sigma)
    b, g, r = cv2.split(gaussian_img)
    smooth_img = (r, g, b)
    print(b.shape, g.shape, r.shape)

    # build graph
    graph = []
    num = 0;

    print("staring segment image")
    for y in range(height):
        for x in range(width):
            if x < width - 1:
                a = y * width + x
                b = y * width + (x + 1)
                # w = 1
                w = diff(smooth_img, x, y, x + 1, y)
                num += 1
                graph.append((a, b, w))

            if y < height - 1:
                a = y * width + x
                b = (y + 1) * width + x
                w = diff(smooth_img, x, y, x, y + 1)
                num += 1
                graph.append((a, b, w))

            if x < width - 1 and y < height - 1:
                a = y * width + x
                b = (y + 1) * width + (x + 1)
                w = diff(smooth_img, x, y, x + 1, y + 1)
                num += 1
                graph.append((a, b, w))

            if x < width - 1 and y > 0:
                a = y * width + x
                b = (y - 1) * width + (x + 1)
                w = diff(smooth_img, x, y, x + 1, y - 1)
                num += 1
                graph.append((a, b, w))
        # print(x, y)

    # sort edges by weight
    # graph.sort(key=lambda x: (x[2]))
    graph = sorted(graph, key=lambda x: (x[2]))
    # segment

    u = segment_graph(width * height, num, graph, c)

    # post process small components
    for i in range(num):
        a = u.find(graph[i][0])
        b = u.find(graph[i][1])
        if (a != b) and ((u.size(a) < min_size) or u.size(b) < min_size):
            u.join(a, b)

    num_ccs.append(u.num_sets())

    colors = []
    for i in range(width * height):
        colors.append(random_rgb())

    print("staring random colors")

    # print("width", width, "height", height)

    for y in range(height):
        for x in range(width):
            comp = u.find(y * width + x)
            gaussian_img[y][x] = colors[comp]

    return gaussian_img


def calc_time(program):
    def wrapper():
        # import time
        t1 = time.time()
        res = program()
        t2 = time.time()

        cost_time = (t2 - t1) * 1000

        print("program run time : %s s" % cost_time)

        return res
    return wrapper


@calc_time
def segment():
    if len(sys.argv) != 6:
        print("usage:", sys.argv[0], "sigma k min input output")
        return 1
    sigma = float(sys.argv[1])
    k = float(sys.argv[2])
    min_size = int(sys.argv[3])

    print("loading input image.")

    input = cv2.imread(sys.argv[4])

    print("processing")

    num_ccs = [];

    cv2.imwrite(sys.argv[5], segment_image(input, sigma, k, min_size, num_ccs))


    print("got", num_ccs[0], "components")
    print("done! uff...thats hard work.");

    return 0


def main():
    segment()


if __name__ == '__main__':
    main()

Reference

Paper:Efficient Graph-Based Image Segmentation

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡同的诗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值