OpenCV - Python 工具函数合集

346 阅读3分钟

算法开发、实现、测试和比较过程中要比较太多乱七八糟的算法。有些论文的算法虽然很简单,但是没有现成的轮子可以用,尤其是在Python中要实现一个高效的轮子是比较困难的事情,所以不得不自己摸索了一些方法。

这些方法没有什么大用,也没有发论文或者工程化的用处,但总归是花了一些时间,所以计划分享出来,如果算法多了,或许会专门去Github开一个仓库整理。

主要使用的是NumPy和OpenCV库,所以默认import

import numpy as np
import cv2

Max-mean Filter 最大均值滤波器

def maxMean(img: np.ndarray, blockSize: int) -> np.np.ndarray:
    """单通道图像,有需求自行修改成多通道"""
    assert len(img.shape) == 2
    rowKernel = np.ones((1, blockSize), dtype=np.uint8) / blockSize
    colKernel = np.ones((blockSize, 1), dtype=np.uint8) / blockSize
    diagKernel = np.identity(blockSize, dtype=np.uint8) / blockSize
    antiKernel = np.rot90(diagKernel)
    kernels = [rowKernel, colKernel, diagKernel, antiKernel]
    result = np.zeros(img.shape, dtype=img.dtype)
    for kernel in kernels:
        result = cv2.max(result, cv2.filter2D(img, -1, kernel))
    return result

adaptiveThreshold with mask 允许使用掩码的自适应阈值化,只部分实现了使用均值卷积核的方法cv2.ADAPTIVE_THRESH_MEAN_C,至于其他卷积核确实没搞明白怎么整

import math
def meanAdaptiveThreshold(src: np.ndarray, mask: np.ndarray, maxValue: int, adaptiveMethod: int, thresholdType: int, blockSize: int, C: int) -> np.ndarray:
    assert src is not None and src.dtype == np.uint8 and len(src.shape) == 2
    assert adaptiveMethod == cv2.ADAPTIVE_THRESH_MEAN_C
    assert thresholdType == cv2.THRESH_BINARY or thresholdType == cv2.THRESH_BINARY_INV

    if mask is not None:
        assert mask.dtype == np.uint8 and len(mask.shape) == 2
        filterSum = cv2.boxFilter(cv2.bitwise_and(src, mask), cv2.CV_32S, (blockSize, blockSize),
                                  normalize=False, borderType=cv2.BORDER_ISOLATED | cv2.BORDER_REPLICATE)
        eleSum = cv2.boxFilter(mask, cv2.CV_32S, (blockSize, blockSize),
                               normalize=False, borderType=cv2.BORDER_ISOLATED | cv2.BORDER_REPLICATE)
        mean = cv2.divide(cv2.multiply(filterSum, 255, dst=filterSum),
                          eleSum, dst=filterSum, dtype=cv2.CV_32S)
    else:
        mean = cv2.boxFilter(src, cv2.CV_32S, (blockSize, blockSize),
                             borderType=cv2.BORDER_ISOLATED | cv2.BORDER_REPLICATE)

    src = src.astype(np.int32)
    idelta = math.ceil(C) if adaptiveMethod == cv2.THRESH_BINARY else math.floor(C)
    thred = cv2.inRange(src - mean, -idelta + 1,
                        256) if thresholdType == cv2.THRESH_BINARY else cv2.inRange(src - mean,  -256, -idelta)
    return thred if mask is None else cv2.bitwise_and(thred, mask)

Python实现Reed-Xiaoli(RX)高光谱目标检测算法

参考Python实现Reed-Xiaoli(RX)高光谱目标检测算法做了速度和空间优化

原文Adaptive multiple-band CFAR detection of an optical pattern with unknown spectral distribution

# 经测试,比CSDN方法快3倍左右
def RXD(mat, segmentWidth = 20):
    """Reed-Xu Detector"""
    rows, cols, chans = mat.shape  
    # 像素数
    area = rows * cols
    # 图像堆叠为像素列表
    stacked = np.reshape(mat, (area, chans))
    # 协方差阵,为避免奇异矩阵可以加一个系数单位阵
    covariance = np.cov(stacked.T) # + np.eye(chans) * 1e-5
    # 协方差矩阵的逆
    invCor = np.linalg.inv(covariance)
    # 图像各通道/波段的均值
    average = stacked.mean(axis=0).reshape((1, -1))
    # 图像减去均值
    stacked = stacked - average
    # 如果图像较大,分块计算加速
    if rows >= 40:
        # 预分配结果的内存空间
        result = np.empty((area,))
        # 分块计算矩阵乘法,加速且节省一点内存,测试了一下分块宽度取20一般不错
        for i in range(segmentWidth, area + 1, segmentWidth):
            delta = stacked[i - segmentWidth : i]
            result[i - segmentWidth : i] = np.diag(
                # @是numpy矩阵乘法
                delta@invCor@delta.T
            )
            
        # 最后的一块矩阵
        remainder = area % segmentWidth
        if remainder > 0:
            delta = stacked[area - remainder : area]
            result[area - remainder : area] = np.diag(
                delta@invCor@delta.T
            )
        # 更改resultshape
        result.resize((rows, cols))
    else:
        delta = stacked[i - segmentWidth : i]
        result = np.diag(
            delta@invCor@delta.T
        )
        result.resize((rows, cols))
    return result

Word标题变成竖线 解决方案

参考文章用宏,亲测有效

下面的具体解决方案来自上述博客,非常感谢! 解决办法: 1.点击菜单栏“视图”, 2.找到“宏“选项卡,点击后弹出下拉选项中选择”查看宏“ 3.弹出的窗口中输入”宏名(例如repair)“,然后点击”创建“,将上面那段宏代码复制粘贴进去。 4.在工具栏找到”运行宏“图标(向右的三角形),点击一下就可以运行了。

宏代码如下:

Sub repair()
 
For Each templ In ActiveDocument.ListTemplates
 
For Each lev In templ.ListLevels
 
lev.Font.Reset
 
Next lev
 
Next templ

blog.csdn.net/u012485480/…