【数字图像处理】二值图和灰度图的形态学处理

文章目录

  • 形态学处理
    • 二值图形态学处理
      • 二值图形态学基本算子
      • 二值图连通分量提取、区域标记
      • 二值图细化算法
    • 灰度图形态学处理
      • 灰度图形态学基本算子
      • 灰度图形态学梯度
      • 灰度图 tophat 算法

形态学处理

二值图形态学处理

二值图形态学基本算子

二值图形态学图像处理通常在目标图像中卷积式地移动一个结构元素并进行逻辑运算。

腐蚀
腐蚀运算的结果是结构元素 B B B平移 x x x后仍包含在目标图像 A A A内的所有 x x x组成的集合:

A ⊙ B = { x ∣ B + x ⊆ A } A\odot B=\{x|B+x\subseteq A\} AB={xB+xA}

也就是说用结构元素找出在目标图像内部可以完全放下该结构元素的值为 1 的区域。腐蚀具有缩小图像中的物体和消除图像中比结构元素小的成分的作用。

膨胀
膨胀运算的结果是结构元素 B B B平移 x x x后与目标图像 A A A至少有 1 个非 0 元素相交时对应的结构元素的原点位置所组成的集合:
A ⊕ B = { x ∣ ( B + x ) ∩ A ≠ ∅ } A\oplus B=\{x|({B}+x)\cap A\neq\emptyset\} AB={x(B+x)A=}

膨胀运算能扩张图像中的物体。


开运算是先腐蚀后膨胀:
A ∘ B = ( A ⊙ B ) ⊕ B A^{\circ}B=(A\odot B)\oplus B AB=(AB)B

能够消除小物体、断开狭窄细长的连接带和平滑图形边缘。


闭运算是先膨胀后腐蚀:

A ⋅ B = ( A ⊕ B ) ⊙ B A\cdot B=(A\oplus B)\odot B AB=(AB)B

能够填充物体内细小空洞、连接邻近物体和平滑图形内边缘。

击中击不中
对于目标图像 A A A和结构元素 B B B,如果 A ∩ B ≠ ∅ A\cap B\not=\emptyset AB=,那么称 B B B击中A; 如果 A ∩ B = ∅ A\cap B=\emptyset AB=, 那么称B击不中A。形态学击中击不中变换表达式为:

A ⊛ B = ( A ⊙ B 1 ) ∩ [ A c ⊙ B 2 ] A\circledast B=\left(A\odot B_1\right)\cap\left[A^c\odot B_2\right] AB=(AB1)[AcB2]

其中 A c = 1 − A A^c=1-A Ac=1A 。通常令 B 2 = 1 − B 1 B_2 = 1 - B_1 B2=1B1 。击中击不中变换可以用来检测特定形状(结构元素的形状)所处位置。

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

np.set_printoptions(threshold=np.inf)
plt.rcParams['font.sans-serif'] = ['SimHei']


def img_erode(bin_im, kernel):
    '''腐蚀'''
    kernel_w = kernel.shape[0]
    kernel_h = kernel.shape[1]

    erode_img = np.zeros(shape=bin_im.shape)
    for i in range(1, bin_im.shape[0] - kernel_w + 2):
        for j in range(1, bin_im.shape[1] - kernel_h + 2):
            a = bin_im[i - 1:i - 1 + kernel_w,
                j - 1:j - 1 + kernel_h]  # 找到每次迭代中对应的目标图像小矩阵
            if np.sum(a * kernel) == np.sum(kernel):  # 判定是否“完全重合”
                erode_img[i, j] = 1
    return erode_img


def img_dilate(bin_im, kernel):
    '''膨胀'''
    kernel_w = kernel.shape[0]
    kernel_h = kernel.shape[1]
    dilate_img = np.zeros(shape=bin_im.shape)
    for i in range(1, bin_im.shape[0] - kernel_w + 1 + 1):
        for j in range(1, bin_im.shape[1] - kernel_h + 1 + 1):
            a = bin_im[i - 1:i - 1 + kernel_w,
                j - 1:j - 1 + kernel_h]
            dilate_img[i, j] = np.max(a * kernel)  # 若“有重合”,则点乘后最大值为0
    return dilate_img


def img_open(bin_im, erope_k, dilate_k):
    '''开:先腐蚀再膨胀'''
    open_img = img_erode(bin_im, erope_k)
    open_img = img_dilate(open_img, dilate_k)
    return open_img


def img_close(bin_im, erope_k, dilate_k):
    '''闭:先膨胀再腐蚀'''
    close_img = img_dilate(bin_im, dilate_k)
    close_img = img_erode(close_img, erope_k)
    return close_img



def hit_and_miss(A, B1, B2):
    A_c = 1 - A
    A_c_B1 = img_erode(A, B1).astype(np.uint8)
    A_c_B2 = img_erode(A_c, B2).astype(np.uint8)
    return A_c_B1 & A_c_B2


def hit_and_miss_cv(A, B1, B2):
    A_c = 1 - A
    A_c_B1 = cv2.erode(A, B1).astype(np.uint8)
    A_c_B2 = cv2.erode(A_c, B2).astype(np.uint8)
    return A_c_B1 & A_c_B2


if __name__ == "__main__":
    img = cv2.imread('proj03-images/wirebond-mask.tif', 0)
    ret, bin_img = cv2.threshold(img, 127, 1, cv2.THRESH_BINARY)

    kernel1 = np.ones(shape=(3, 3))  # 结构元素,可以为非规则形状
    kernel2 = np.ones(shape=(3, 3))  # 同上


    erode_im = img_erode(bin_img, kernel1)
    dilate_im = img_dilate(bin_img, kernel1)
    open_im = img_open(bin_img, kernel1, kernel2)
    close_im = img_close(bin_img, kernel1, kernel2)

    # erode_im = cv2.erode(img, kernel2)
    # dilate_im = cv2.dilate(img, kernel2)
    # open_im = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel=kernel1)
    # close_im = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel=kernel1)


    kernel1 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).astype(np.uint8)
    kernel2 = 1 - kernel1
    img_hit_and_miss = hit_and_miss(bin_img, kernel1, kernel2)
    #img_hit_and_miss = hit_and_miss_cv(bin_img, kernel1, kernel2)

    print(np.sum(img_hit_and_miss))


    plt.subplot(231)
    plt.title("(a)二值图像", y=-0.2)
    plt.imshow(bin_img, cmap="gray")
    plt.subplot(232)
    plt.title("(b)腐蚀运算", y=-0.2)
    plt.imshow(erode_im, cmap="gray")
    plt.subplot(233)
    plt.title("(c)膨胀运算", y=-0.2)
    plt.imshow(dilate_im, cmap="gray")
    plt.subplot(234)
    plt.title("(d)开运算", y=-0.2)
    plt.imshow(open_im, cmap="gray")
    plt.subplot(235)
    plt.title("(e)闭运算", y=-0.2)
    plt.imshow(close_im, cmap="gray")
    plt.subplot(236)
    plt.title("(f)击中-击不中", y=-0.2)
    plt.imshow(img_hit_and_miss, cmap="gray")
    plt.show()

二值图连通分量提取、区域标记

将原图中的一个非零点不断膨胀,然后与原图相交,得到连通分量,之后将连通分量从原图去掉;循环以上操作获取多个连通分量,直到原图全为 0:

X k = ( X k − 1 ⊕ B ) ∩ A , k = 1 , 2 , 3 , … X_{\mathrm{k}}=\begin{pmatrix}X_{k-1}\oplus B\end{pmatrix}\cap A,k=1,2,3,\ldots Xk=(Xk1B)A,k=1,2,3,

X 0 X_0 X0为标记点,可指定或随机选取。

import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']


def extract_connected_components(src):
 # 提取连通分量
    num_pixels = []  # 保存连通分量中的像素个数
    img_pixels = []  # 保存对应连通分量的图像

    canvas = np.zeros(src.shape, dtype=np.uint8)  # 将每次提取的连通分量放到这里
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 3×3结构元做膨胀运算

    x, y = np.where(src > 0)  # 获取图像中值为1的点
    canvas[x[0]][y[0]] = 1  # 以第一个点为起始点

    while src.any():  # src 矩阵内部所有元素为零的时候,为False
        count = len(x)  # 求每个连通分量的像素点数
        tmp = canvas  # tmp暂存上一步的迭代操作

        src_dilate = cv2.dilate(canvas, kernel)  # 膨胀
        canvas = cv2.bitwise_and(src, src_dilate)  # 和原图求交集

        if (tmp == canvas).all():  # 判断两次迭代操作是否相等。相等的时候,一次提取结束;否则,继续迭代
            img_pixels.append(canvas)  # 将连通分量图片保存到列表
            src[canvas > 0] = 0  # 将该次的连通分量去掉
            canvas = np.zeros(src.shape, np.uint8)  # 将每次提取的连通分量放到这里

            x, y = np.where(src > 0)  # 获取图像中的前景像素点
            num_pixels.append(count - len(x))  # 将上次的点数 - 下次的点数 = 提取连通分量的像素点个数

            if len(x) != 0:  # src 还有前景像素的时候
                canvas[x[0]][y[0]] = 1  # 取起始点

    return num_pixels, img_pixels  # 返回每个连通分量个数和连通分量图像



def mark_connected_components(img,num):
    output = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
    for i in range(0, num):
        mask = dst[i] == 1
        output[:, :, 0][mask] = np.random.randint(0, 255)
        output[:, :, 1][mask] = np.random.randint(0, 255)
        output[:, :, 2][mask] = np.random.randint(0, 255)

    return output
img = cv2.imread("proj03-images/Chickenfilet with bones.tif", flags=0)


ret, img_bin = cv2.threshold(img, 200, 1, cv2.THRESH_BINARY)  # 二值化处理
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 3×3结构元
img_erode = cv2.erode(img_bin, kernel)

num, dst = extract_connected_components(img_erode.copy())  # 传入拷贝图像
print(len(num))  # 打印连通分量的像素点个数

cv2.imshow('img', img_erode * 255)
cv2.waitKey()

output=mark_connected_components(img_erode,len(num))
cv2.imshow('output', output)
cv2.waitKey(0)


# # OpenCV
# num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(img_erode, connectivity=8)
#
#
# print('各连通量的点数:',np.sort(stats[1:,-1]))
#
# # 不同的连通域赋予不同的颜色
# output = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
# for i in range(1, num_labels):
#     mask = labels == i
#     output[:, :, 0][mask] = np.random.randint(0, 255)
#     output[:, :, 1][mask] = np.random.randint(0, 255)
#     output[:, :, 2][mask] = np.random.randint(0, 255)
# cv2.imshow('oginal', output)
# cv2.waitKey()
# cv2.destroyAllWindows()

对提取到的连通分量用不同颜色进行区域标记,得到最终结果:

原图结果
在这里插入图片描述

二值图细化算法

使用击中击不中获取与结构元素相同形状的图像边缘像素,然后将其删除,通过迭代多
次最终得到单像素宽带骨架。对于结构元素组:
{ B } = { B 1 , B 2 , B 3 , … , B n } \{B\}=\left\{B_{1},B_{2},B_{3},\ldots,B_{n}\right\} {B}={B1,B2,B3,,Bn}

对目标图像 A A A使用击中-击不中细化:

A = A ⊗ B i = A − ( A ⊛ B i ) , i = 1 , 2 , . . . , n A=A\otimes B_{i}=A-(A\circledast B_{i}),i=1,2,...,n A=ABi=A(ABi),i=1,2,...,n

如果在迭代过程中, ⊛ \circledast 操作后 A A A没有变化,则结束细化,输出细化结果。

import cv2

import numpy as np
def thin(img):
    hit1 = np.array([[0, 0, 0], [1, 1, 1], [1, 1, 1]])
    hit2 = np.array([[1, 0, 0], [1, 1, 0], [1, 1, 1]])
    hit3 = np.array([[0, 0, 0], [1, 1, 1], [1, 1, 1]])
    hit4 = np.array([[1, 1, 0], [1, 1, 0], [1, 1, 0]])
    hit5 = np.array([[1, 1, 1], [1, 1, 1], [0, 0, 0]])
    hit6 = np.array([[1, 1, 1], [0, 1, 1], [0, 0, 1]])
    hit7 = np.array([[0, 1, 1], [0, 1, 1], [0, 1, 1]])
    hit8 = np.array([[1, 1, 0], [1, 0, 0], [0, 0, 0]])
    kernels = [hit1, hit2, hit3, hit4, hit5, hit6, hit7, hit8]
    dst = img.copy()
    while True:
        tmp = dst
        for kernel in kernels:
            dst = dst - hit_and_miss(dst, kernel,  1-kernel)
        if (dst == tmp).all():
            return dst
        print(np.sum(dst != tmp))
img2 = cv2.imread("UTK.tif", 0)


ret2, img_bin2 = cv2.threshold(img2, 100, 1, cv2.THRESH_BINARY)  # 二值化处理



img_thin = thin(img_bin2)
cv2.imshow('img', img_bin2 * 255)
cv2.imshow('img_thin', img_thin * 255)
cv2.waitKey(0)

原图结果
在这里插入图片描述在这里插入图片描述

灰度图形态学处理

灰度图形态学基本算子

腐蚀
在灰度图像中,用结构元素 b ( x , y ) b(x,y) b(x,y)对输入图像 f ( x , y ) f(x,y) f(x,y)进行灰度腐蚀运算可表示为:

( f ⊙ b ) ( s , t ) = min ⁡ { f ( s + x , t + y ) ∣ ( s + x , t + y ) ∈ D f ; ( x , y ) ∈ D b } (f\odot b)(s,t)=\min\left\{f(s+x,t+y)|(s+x,t+y)\in D_{f};(x,y)\in D_{b}\right\} (fb)(s,t)=min{f(s+x,t+y)(s+x,t+y)Df;(x,y)Db}

式中, D f D_f Df D b D_b Db分别是 f ( x , y ) f(x,y) f(x,y) b ( x , y ) b(x,y) b(x,y)的定义域。求某点的腐蚀运算就是计算该点结构元素覆盖范围内各点最小值作为该点的腐蚀结果。 经腐蚀运算后,图像暗的区域范围将扩大。

膨胀
用结构元素 b ( x , y ) b(x,y) b(x,y)对输入图像 f ( x , y ) f(x,y) f(x,y)进行灰度膨胀运算可表示为:

( f ⊕ b ) ( s , t ) = max ⁡ { f ( s − x , t − y ) ∣ ( s − x , t − y ) ∈ D f ; ( x , y ) ∈ D b } (f\oplus b)(s,t)=\max\left\{f(s-x,t-y)|(s-x,t-y)\in D_f;(x,y)\in D_b\right\} (fb)(s,t)=max{f(sx,ty)(sx,ty)Df;(x,y)Db}

求某点的膨胀运算就是计算该点局部范围内各点的最大值作为该点的膨胀结果。经膨胀运算后,图像亮的区域范围将扩大。


开运算是先腐蚀后膨胀:
f ॰ b = ( f ⊙ b ) ⊕ b f^\text{॰}b=(f\odot b)\oplus b fb=(fb)b

开运算操作可以消除相对于结构元素尺寸较小的亮细节。


闭运算是先膨胀后腐蚀:

f ∙ b = ( f ⊕ b ) ⊙ b f\bullet b=(f\oplus b)\odot b fb=(fb)b

闭运算操作可以消除相对于结构元素尺寸较小的暗细节。



import numpy as np
import cv2
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']


def img_erode(image, kernel, num=2):
    iChange = image.copy()
    num = int((kernel.shape[1] - 1) / 2)
    image = cv2.copyMakeBorder(image, num, num, num, num, 0)
    w = iChange.shape[1]
    h = iChange.shape[0]
    for i in range(h):
        for j in range(w):
            a = image[i:i + 2 * num+1, j:j + 2 * num+1]  # - kernel
            iChange[i, j] = np.min(a)
    return iChange


def img_dilate(image, kernel, num=2):
    iChange = image.copy()
    num = int((kernel.shape[1] - 1) / 2)
    image = cv2.copyMakeBorder(image, num, num, num, num, 0)
    w = iChange.shape[1]
    h = iChange.shape[0]
    for i in range(h):
        for j in range(w):
            a = image[i:i + 2 * num+1, j:j + 2 * num+1]  # - kernel
            iChange[i, j] = np.max(a)
    return iChange


def img_open(img, erope_k, dilate_k):
    '''开:先腐蚀再膨胀'''
    open_img = img_erode(img, erope_k)
    open_img = img_dilate(open_img, dilate_k)
    return open_img


def img_close(img, erope_k, dilate_k):
    '''闭:先膨胀再腐蚀'''
    close_img = img_dilate(img, dilate_k)
    close_img = img_erode(close_img, erope_k)
    return close_img


if __name__ == '__main__':
    img = cv2.imread("ckt_board_section.tif", flags=0)


    kernel1 = np.ones(shape=(5, 5))  # 此处声明结构元素,可以自定义为非规则形状
    kernel2 = np.ones(shape=(5, 5))  # 同上

    erode_im = img_erode(img, kernel1)
    dilate_im = img_dilate(img, kernel1)
    open_im = img_open(img, kernel1, kernel2)
    close_im = img_close(img, kernel1, kernel2)

    # erode_im = cv2.erode(img, kernel2)
    # dilate_im = cv2.dilate(img, kernel2)
    # open_im1 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel=kernel1)
    # close_im = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel=kernel1)

    plt.subplot(231)
    plt.title("(a)二值图像", y=-0.2)
    plt.imshow(img, cmap="gray")
    plt.subplot(232)
    plt.title("(b)腐蚀运算", y=-0.2)
    plt.imshow(erode_im, cmap="gray")
    plt.subplot(233)
    plt.title("(c)膨胀运算", y=-0.2)
    plt.imshow(dilate_im, cmap="gray")
    plt.subplot(234)
    plt.title("(d)开运算", y=-0.2)
    plt.imshow(open_im, cmap="gray")
    plt.subplot(235)
    plt.title("(e)闭运算", y=-0.2)
    plt.imshow(close_im, cmap="gray")
    plt.show()

在这里插入图片描述

灰度图形态学梯度

灰度图形态学梯度用膨胀运算结果减去腐蚀运算的结果,表达式为:

g = ( f ⊕ b ) − ( f ⊙ b ) g=(f\oplus b)-(f\odot b) g=(fb)(fb)

可用于提取灰度图的边缘。

原图结果
在这里插入图片描述在这里插入图片描述

灰度图 tophat 算法

灰度图 tophat 算法用原图像减去开运算结果,表达式为:
h = f − f ∘ b h=f-f^{\circ}b h=ffb

可用于提取出灰度图中较亮的细节。

原图结果

import cv2
def grad(img, erope_k, dilate_k):
    '''形态学梯度'''
    dilate_img = img_dilate(img.copy(), dilate_k)
    erode_img = img_erode(img.copy(), erope_k)
    return dilate_img - erode_img


def tophat(img, erope_k, dilate_k):
    open_img = img_open(img, erope_k, dilate_k).astype(np.uint8)
    # open_img=cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel=dilate_k)
    return (img - open_img)


if __name__ == '__main__':
    img1 = cv2.imread("headCT-Vandy.tif", 0)
    img2 = cv2.imread("rice_image_with_intensity_gradient.tif", 0)
    kernel3 = np.ones(shape=(5, 5))  # 此处声明结构元素,可以自定义为非规则形状
    kernel4 = np.ones(shape=(21, 21))  # 同上

    # 实现
    # grad_im = grad(img1, kernel3, kernel3)
    # tophat_im = tophat(img2, kernel4, kernel4)

    # OpenCV
    grad_im = cv2.morphologyEx(img1, cv2.MORPH_GRADIENT, kernel3)
    tophat_im = cv2.morphologyEx(img2, cv2.MORPH_TOPHAT, kernel4)

    cv2.imshow('grad_im', grad_im)
    cv2.waitKey(0)
    cv2.imshow('img2', img2)
    cv2.imshow('tophat_im', tophat_im)
    cv2.waitKey(0)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/529557.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据处理包Pandas】多级索引的创建及使用

目录 一、元组作为一级索引(一)示例1(二)示例2 二、引入多级索引(一)多级索引的创建(二)多级索引中的数学选取 首先,导入 NumPy 库和 Pandas 库。 import numpy as np i…

javaWeb影视创作论坛的设计与实现

摘要 随着时代的发展,互联网的出现,给传统影视行业带来的最大便利就是,方便了影视从业人员以及爱好者的交流和互动,而为用户提供一个书写影评,阅读影评以及回复影评的平台,以影评为载体来使用户感受影评、…

openharmony launcher 调研笔记(03)UI 数据装配

最近在看launcher,把自己调研的点做个笔记,持续修改更新中,个人笔记酌情参考。 桌面上半部分包含父子逻辑: Column() { PageDesktopLayout(); } PageDesktopLayout->GridSwiper->Swiper->SwiperPage 1.PageDe…

无重复的最长字串

📝个人主页:五敷有你 🔥系列专栏:算法分析与设计 ⛺️稳中求进,晒太阳 问题 给定一个字符串,我们需要找到该字符串中的最长无重复子串的长度。 示例 让我们以一个具体的示例来说明这个问题&#…

数据结构---线性表

1&#xff0c;顺序表实现---动态分配 #include<stdlib.h> #define InitSize 10 typedef struct {int *data;//静态分配int length;int MaxSize; }SqList; void InitList(SqList& L) {L.data (int*)malloc(InitSize * sizeof(int));//分配空间L.length 0;L.MaxSize…

企业如何管理员工技能,提升人员管理质效?

最近总有客户来抱怨&#xff0c;传统集团由于企业规模庞大、员工分散及线下管理模式局限&#xff0c;导致HR部门工作效率不高&#xff0c;无法及时解决一线员工的岗位排班、员工技能水平变更等问题。 正好&#xff0c;最近我们有类似成功案例和大家分享一下。 我们特意邀请到…

猫头虎分享已解决Error: 解决“IndexError: list index out of range“

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 文章目录 猫头虎分享已解决Error: 解决"IndexError: list index out of range" &#x1f431;&#x1f989;&#x1f6e0;️摘要正文内容一、错误现场勘察 &#x1f575…

关于Linux内核code段被改写的原因分析

本文基于Linux-4.19.125&#xff0c; ARM V7&#xff0c;dual core。 1 code 段 Linux的code段&#xff08;或者说text段&#xff09;自_stext开始&#xff0c;到_etext结束&#xff0c;这段内容一般情况下是只读的&#xff0c;在理论上来说&#xff0c;这段数据在设备上应该…

如何在淘~宝接单和解决别人问题-java开发

如下这是一个连接&#xff1a;https://s.tb.cn/c.0vDtL3https://s.tb.cn/c.0vDtL3 解决各种问题。可付费咨询

初识C++ · 类和对象(上)

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1 访问限定符 4.2 封装 5.类的作用域 6.类的实例化 7.类的对象大小的计算 8.类成员函数的this指针 1.面向过程和面向对象初步认识 C语言是一门面向过程的语言&#xff0c;注重的…

FPGA(Verilog)实现按键消抖

实现按键消抖功能&#xff1a; 1.滤除按键按下时的噪声和松开时的噪声信号。 2.获取已消抖的按键按下的标志信号。 3.实现已消抖的按键的连续功能。 Verilog实现 模块端口 key_filter(input wire clk ,input wire rst_n ,input wire key_in , //按下按键时为0output …

《QT实用小工具·二十二》多种样式导航按钮控件

1、概述 源码放在文章末尾 该项目实现了多种样式的导航按钮控件 可设置文字的左侧、右侧、顶部、底部间隔。 可设置文字对齐方式。 可设置显示倒三角、倒三角边长、倒三角位置、倒三角颜色。 可设置显示图标、图标间隔、图标尺寸、正常状态图标、悬停状态图标、选中状态图标…

纯C语言手搓GPT-2,前OpenAI、特斯拉高管新项目火了

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 「Real men program in C.」 众所周知&#xff0c;大语言模型还在快速发展&#xff0c;应该有…

自动驾驶基础技术-无迹卡尔曼滤波UKF

自动驾驶基础技术-无迹卡尔曼滤波UKF Unscented Kalman Filter是解决非线性卡尔曼滤波的另一种思路&#xff0c;它利用Unscented Transform来解决概率分布非线性变换的问题。UnScented Kalman Filter不需要像Extended Kalman Filter一样计算Jacobin矩阵&#xff0c;在计算量大…

Vue - 你知道Vue2中对象动态新增属性,视图无法更新的原因吗

难度级别:中高级及以上 提问概率:55% 这道题面试官会这样描述,比如有这样一个场景,一个对象里有name属性,可以正常显示在页面中。但后续动态添加了一个age属性,通过调试打印发现对象里的age属性已经添加了上了,但试图中却没有展示出来,…

程序语言基础

根据希赛相关视频课程汇总整理而成&#xff0c;个人笔记&#xff0c;仅供参考。考点偏向于通用程序语言的基础概念。 程序语言基础概念 程序设计语言&#xff1a; ①低级语言 机器语言汇编语言 汇编语言&#xff1a;指令语句/伪指令语句/宏指令语句 ②高级语言 Fotrane语言&…

计算系数(acwing,数论)

题目描述&#xff1a; 给定一个多项式 (axby)^k&#xff0c;请求出多项式展开后 x^n*y^m 项的系数。 输入格式&#xff1a; 共一行&#xff0c;包含 5 个整数&#xff0c;分别为 a&#xff0c;b&#xff0c;k&#xff0c;n&#xff0c;m&#xff0c;每两个整数之间用一个空格…

2024马来西亚电商选品博览会

2024马来西亚电商选品博览会 展会概况 展会名称&#xff1a;2024马来西亚电商选品博览会 主办单位&#xff1a;广东进出口商会 时间:2024.11.29-12.1 地点&#xff1a;马来西亚国际贸易展览中心(MITEC) 展览面积&#xff1a;10000平方米 展会简介 2024马来西亚跨境电商选…

vue2 父子组件通讯

父传子 父组件&#xff1a;app.vue <template><div>app 父组件<!-- 2.动态绑定定义的数据 --><LiCount :title"mytitle"></LiCount></div> </template><script> import LiCount from "./components/LiCount.…

自定义的@TableField,解决插入或更新失效

自定义的TableField&#xff0c;解决插入或更新失效 01 使用场景 需要使用到mybatisplus的自动填充时 02 配置类和扫描包 在启动类处配置扫描包&#xff0c;每次启动扫描配置类 配置类 package com.ruoyi.framework.hander;import com.baomidou.mybatisplus.core.handlers.…