Opencv Python图像处理笔记一:图像、窗口基本操作

文章目录

  • 前言
  • 一、输入输出
    • 1.1 图片读取显示保存
    • 1.2 视频读取保存
    • 1.3 文件读取保存
  • 二、GUI
    • 2.1 窗口
    • 2.2 轨迹条
    • 2.3 画图
    • 2.4 鼠标回调
  • 三、图像入门操作
    • 3.1 颜色空间转化
    • 3.2 通道分离合并
    • 3.3 添加边框
    • 3.4 算数操作
  • 四、二值化
    • 4.1 普通
    • 4.2 自适应
    • 4.3 Otsu
  • 参考

前言

随着人工智能和计算机视觉技术的迅猛发展,OpenCV(Open source Computer Vision library)成为了广大开发者和研究者们不可或缺的利器之一。OpenCV 是一个开源的计算机视觉库,提供了丰富的图像处理和计算机视觉算法,涵盖了从简单的图像处理操作到复杂的目标检测和跟踪等领域。

本文旨在帮助读者系统地学习 Opencv Python,从基础的图像输入输出开始,逐步深入到图像处理的各个领域,涵盖 GUI 编程、图像操作、二值化等多个重要主题。无论您是初学者还是有经验的开发者,本文都将提供清晰的指导和实用的示例,帮助您快速掌握 Opencv Python 的应用技巧。

  • github

    • https://github.com/opencv/opencv-python
    • https://github.com/opencv/opencv
  • 安装

    pip install opencv-python
    

一、输入输出

1.1 图片读取显示保存

import sys
import cv2 as cv

def main():   
    img = cv.imread("alice_color.png")
    if img is None:
        sys.exit("Could not read the image.")
    cv.imshow("Display window", img)
    k = cv.waitKey(0)
    if k == ord("q"):
        roi = img[100: 200, 100:200]
        roi[:] = 0
        cv.imwrite("alice_color_change.png", img)

if __name__ == '__main__':
    main()

demo01

1.2 视频读取保存

import cv2 as cv


def main():
    # 定义解码器 MJPG (.mp4), DIVX (.avi), X264 (.mkv)
    fourcc = cv.VideoWriter_fourcc(*'MJPG')
    # 设置 帧率 分辨率
    # 注意, 这里设置分辨率需要与你摄像头或者读取的文件的分辨率保持一致, 否则不会写入数据
    out = cv.VideoWriter('output.avi', fourcc, 20.0, (960, 506))

    # cap = cv.VideoCapture(0)
    cap = cv.VideoCapture('test.mp4')
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    while True:
        # Capture frame-by-frame
        ret, frame = cap.read()
        # if frame is read correctly ret is True
        if not ret:
            print("Can't receive frame (stream end?). Exiting ...")
            break
        # Our operations on the frame come here
        cv.waitKey(1)
        cv.imshow('frame', frame)
        # 翻转图像
        frame = cv.flip(frame, 0)

        out.write(frame)

    # When everything done, release the capture
    cap.release()
    out.release()
    cv.destroyAllWindows()


if __name__ == '__main__':
    main()

demo_02_video_read_write

1.3 文件读取保存

opencv 还支持持久化,将数据以xml,yml,json文件保存,并读取

import cv2 as cv
import numpy as np

def main():
    write()
    read()

def write():  

    # 创建FileStorage对象并打开一个文件用于写入
    fs = cv.FileStorage('test.xml', cv.FILE_STORAGE_WRITE)
    
    # 写入一些数据
    fs.write('First_Integer', 123)
    fs.write('First_String', 'Hello')
    
    # 写入一个矩阵
    mat = np.eye(2, 3, dtype=np.uint8)
    fs.write('Matrix', mat)
    
    # 写入一个复杂的数据结构
    fs.write('List', (1, 2, 3))
    
    # 关闭FileStorage对象
    fs.release()

def read():
    fs = cv.FileStorage('test.xml', cv.FILE_STORAGE_READ)
 
    # 读取数据
    if not fs.isOpened():
        print("Error: Unable to open file.")
        exit()

    First_Integer = fs.getNode('First_Integer').real()
    First_String = fs.getNode('First_String').string()
    Matrix = fs.getNode('Matrix').mat()
    List = fs.getNode('List').mat()

    print(First_Integer)
    print(First_String)
    print(Matrix)
    print(List)

    fs.release()
    
if __name__ == '__main__':
    main()

demo_03_xml_file.png

二、GUI

2.1 窗口

import cv2 as cv
import numpy as np

def main():
    # 名字为first 和second 两个窗口
    # cv.namedWindow(窗口名称, 窗口属性)
    """
    WindowFlags:
        WINDOW_NORMAL : user can resize the window
        WINDOW_AUTOSIZE : user cannot resize the window, the size is constrainted by the image displayed 
        WINDOW_OPENGL : window with opengl support
        WINDOW_FULLSCREEN : change the window to fullscreen
        WINDOW_FREERATIO : the image expends as much as it can 自由比例 
        WINDOW_KEEPRATIO : 保持比例
        WINDOW_GUI_EXPANDED : status bar and tool bar
        WINDOW_GUI_NORMAL  : old fashious way
    """
    cv.namedWindow('first', cv.WINDOW_AUTOSIZE)
    cv.namedWindow('second', cv.WINDOW_NORMAL)

    img = cv.imread('alice_color.png')
    img_changed = cv.imread('alice_color_change.png')

    cv.imshow('first', img)

    # 更改窗口尺寸
    cv.resizeWindow('second', 640, 640)
    cv.imshow('second', img_changed)
    
    # 等待键盘输入,参数为等待时长,单位: ms。0为无限等待
    k = cv.waitKey(0)
    if k == ord("q"):
        cv.destroyAllWindows()
        

if __name__ == '__main__':
    main()

demo_04_windows

2.2 轨迹条

import cv2 as cv
import numpy as np

def callback(index):
    pass

def main():
    winname = "trackbar"
    cv.namedWindow(winname, cv.WINDOW_NORMAL)
    cv.resizeWindow(winname, 640, 480)

    # 创建trackbar控件
    # argument:
    # trackbarname, winname, value, count, callback, userdata
    cv.createTrackbar('R', winname, 0, 255, callback)
    cv.createTrackbar('G', winname, 0, 255, callback)
    cv.createTrackbar('B', winname, 0, 255, callback)

    # 创建初始图像
    img = np.zeros(shape=(640, 480, 3), dtype=np.uint8)

    # 显示图像:
    while True:
        # 读取控件值:
        r = cv.getTrackbarPos('R', winname)
        g = cv.getTrackbarPos('G', winname)
        b = cv.getTrackbarPos('B', winname)

        # b,g,r这个通道数, 在opencv中, rgb通道数是反过来的
        img[:] = [b, g, r]

        # 显示图像
        cv.imshow(winname, img)

        # 等待键盘
        if cv.waitKey(1) & 0xFF == ord('q'):
            break

    cv.destroyAllWindows()
        

if __name__ == '__main__':
    main()

demo_05_trackbar

2.3 画图

import cv2 as cv
import numpy as np
from PIL import Image, ImageDraw, ImageFont


def paint_chinese_opencv(im, textstr, position, fontsize, color):
    # opencv输出中文
    img_PIL = Image.fromarray(cv.cvtColor(
        im, cv.COLOR_BGR2RGB))  # 图像从OpenCV格式转换成PIL格式
    font = ImageFont.truetype(
        r'C:\Windows\Fonts\simfang.ttf', fontsize, encoding="utf-8")
    # color = (255,0,0) # 字体颜色
    # position = (100,100)# 文字输出位置
    draw = ImageDraw.Draw(img_PIL)
    draw.text(
        position, textstr, font=font,
        fill=color)
    img = cv.cvtColor(np.asarray(img_PIL), cv.COLOR_RGB2BGR)  # PIL图片转OpenCV 图片
    return img


def main():
    img = np.zeros((512, 512, 3), np.uint8)

    # 划线
    cv.line(img,
            (0, 0), (511, 511),  # 两点
            color=(255, 0, 0),  # 颜色
            thickness=5,  # 线宽,默认为1
            lineType=4)  # 线类型 有 cv.FILLED, cv.LINE_4, cv.LINE_8, cv.LINE_AA 这4种, 默认为LINE_8,

    # 画矩形,左上角和右下角,其余同上
    cv.rectangle(img, pt1=(384, 0), pt2=(510, 128), color=(0, 255, 0))

    # 画圆,圆心,半径
    cv.circle(img, center=(447, 63), radius=63,
              color=(0, 0, 255), thickness=cv.FILLED)

    # 画椭圆
    cv.ellipse(img,
               center=(256, 256),  # 中心坐标
               axes=(100, 50),  # 长轴,短轴 一半
               angle=0,  # 椭圆沿逆时针方向的旋转角度
               startAngle=0,
               endAngle=180,  # 开始角和结束角表示从主轴向顺时针方向测量的椭圆弧的开始和结束
               color=255,  # 颜色
               thickness=2,
               lineType=cv.FILLED)

    pts = np.array([[10, 5], [20, 30], [70, 20], [50, 10]], np.int32)
    pts = pts.reshape((-1, 1, 2))

    cv.polylines(img, [pts],
                 isClosed=True,  # 是否闭合
                 color=(0, 255, 255))

    cv.putText(img, text='OpenCV',
               org=(10, 500),  # 左下角
               fontFace=cv.FONT_HERSHEY_SIMPLEX,  # 字体
               fontScale=4, # 字体缩放
               color=(255, 255, 255),
               thickness=2,
               lineType=cv.LINE_AA)

    img = paint_chinese_opencv(img, '中文', (255, 255), 40, (255, 255, 255))

    cv.imshow('draw', img)
    k = cv.waitKey(0)
    if k == ord("q"):
        cv.destroyAllWindows()


if __name__ == '__main__':
    main()

demo_06_draw

2.4 鼠标回调

import cv2 as cv
import numpy as np


# 生成全黑图像
img = np.zeros((480, 640, 3), np.uint8)  

# 定义鼠标回调函数画圆
def draw_circle(event,x,y,flags,param):
    # 左键双击
    if event == cv.EVENT_LBUTTONDBLCLK:
        cv.circle(img,(x,y),50,(255,255,0),-1)



def main():
    WINDOW_NAME = "mouse"
    # 创建桌面
    cv.namedWindow(WINDOW_NAME, cv.WINDOW_NORMAL)
    cv.resizeWindow(WINDOW_NAME, 640, 480)

    # 设置鼠标回调, 绑定窗口
    cv.setMouseCallback(WINDOW_NAME, draw_circle, "123")

    # 显示图像
    while True:
        cv.imshow(WINDOW_NAME, img)
        if cv.waitKey(20) & 0xFF == ord('q'):
            break

    cv.destroyAllWindows()
        

if __name__ == '__main__':
    main()

demo_07_mouse

三、图像入门操作

3.1 颜色空间转化

import cv2 as cv
import numpy as np


def callback(index):
    pass


def main():
    winname = "color"
    trackbarname = "colorspace"
    cv.namedWindow(winname, flags=cv.WINDOW_NORMAL)
    cv.resizeWindow(winname, 600, 800)

    color_space_list = [cv.COLOR_BGR2RGB, cv.COLOR_BGR2BGRA,
                        cv.COLOR_BGR2GRAY, cv.COLOR_BGR2HSV, cv.COLOR_BGR2YUV]  # 格式转换队列

    # 创建Trackbar
    cv.createTrackbar(trackbarname, winname, 0, len(
        color_space_list)-1, callback)

    # 读取图片
    img = cv.imread("alice_color.png")

    # 显示图像
    while True:
        color_space_index = cv.getTrackbarPos(trackbarname, winname)

        # 颜色空间转换 -> cvtColor(src, colorSpace)颜色转换
        cvt_img = cv.cvtColor(img, color_space_list[color_space_index])

        cv.imshow(winname, cvt_img)

        if cv.waitKey(1) & 0xFF == ord('q'):
            break
    cv.destroyAllWindows()


if __name__ == '__main__':
    main()

color

3.2 通道分离合并

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


def main():
    img = cv.imread("lena.png")

    # 分割出来的b,g,r每一个都是一个单个矩阵.
    # b, g, r = cv.split(img)
    # 直接操作可以用索引
    b, g, r = img[:, :, 0], img[:, :, 1], img[:, :, 2]

    zeros = np.zeros(img.shape[:2], dtype='uint8')

    title = ['ORIGINAL', 'B', 'G', 'R']
    # 对应的图像
    imgs = [img, cv.merge([b, zeros, zeros]), cv.merge(
        [zeros, g, zeros]), cv.merge([zeros, zeros, r])]

    for i in range(len(imgs)):
        plt.subplot(2, 2, i + 1)
        plt.imshow(cv.cvtColor(imgs[i], cv.COLOR_BGR2RGB))
        plt.title(title[i])
        plt.axis('off')

    plt.show()

    cv.waitKey(0)

    cv.destroyAllWindows()


if __name__ == '__main__':
    main()

demo_09_color_channel

3.3 添加边框

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


def main():
    BLUE = [255, 0, 0]

    img1 = cv.imread('lena.png')
    assert img1 is not None, "file could not be read, check with os.path.exists()"

    width = 20
    # cv.BORDER_REPLICATE 边界颜色被复制                    eg: aaaaaa|abcdefgh|hhhhhhh
    # cv.BORDER_REFLECT  边界颜色被镜像                     eg: fedcba|abcdefgh|hgfedcb
    # cv.BORDER_REFLECT_101  和上面类似,有点不同,这是默认值 eg: gfedcb|abcdefgh|gfedcba
    # cv.BORDER_WRAP                                       eg: cdefgh|abcdefgh|abcdefg
    # cv.BORDER_CONSTANT  给定边界颜色
    replicate = cv.copyMakeBorder(
        img1, width, width, width, width, cv.BORDER_REPLICATE)
    reflect = cv.copyMakeBorder(
        img1, width, width, width, width, cv.BORDER_REFLECT)
    reflect101 = cv.copyMakeBorder(
        img1, width, width, width, width, cv.BORDER_REFLECT_101)
    wrap = cv.copyMakeBorder(img1, width, width, width, width, cv.BORDER_WRAP)
    constant = cv.copyMakeBorder(
        img1, width, width, width, width, cv.BORDER_CONSTANT, value=BLUE)

    title = ['ORIGINAL', 'REPLICATE', 'REFLECT',
             'REFLECT_101', 'WAP', 'CONSTANT']
    # 对应的图像
    imgs = [img1, replicate, reflect, reflect101,
            wrap, constant]

    for i in range(len(imgs)):
        plt.subplot(2, 3, i + 1)
        plt.imshow(cv.cvtColor(imgs[i], cv.COLOR_BGR2RGB))
        plt.title(title[i])
        plt.axis('off')

    plt.show()


if __name__ == '__main__':
    main()

border

3.4 算数操作

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


def main():

    img = cv.imread('lena.png')
    img_girl = cv.imread('girl.png')
    assert img & img_girl is not None, "file could not be read, check with os.path.exists()"

    pixel = img[255, 255]
    print(pixel)                    # [ 78  70 181]
    print(pixel.dtype)              # uint8
    print(img.item(255, 255, 2))    # 181

    x = np.uint8([250])
    y = np.uint8([10])

    print(cv.add(x, y, dtype=cv.CV_8UC3))  # [[255],[0],[0],[0]]
    print(x + y)  # [6]

    # 两张图片按照权重叠加,需要宽高一样大
    img_new = cv.addWeighted(img_girl, 0.7, img, 0.3, 0)

    # 对图片进行位运算 取反、与、或、异或
    img_bit_not = cv.bitwise_not(img)
    img_bit_and = cv.bitwise_and(img, img_girl)
    img_bit_or = cv.bitwise_or(img, img_girl)
    img_bit_xor = cv.bitwise_xor(img, img_girl)

    title = ['Lena', 'Girl', 'addWeight', 'Not', 'And', 'Or', 'Xor']
    # 对应的图像
    imgs = [img, img_girl, img_new, img_bit_not,
            img_bit_and, img_bit_or, img_bit_xor]

    for i in range(len(imgs)):
        plt.subplot(3, 3, i + 1)
        plt.imshow(cv.cvtColor(imgs[i], cv.COLOR_BGR2RGB))
        plt.title(title[i])
        plt.axis('off')

    roi = img_girl[280:340, 330:390]
    roi[:] = 255
    plt.subplot(338), plt.imshow(cv.cvtColor(img_girl, cv.COLOR_BGR2RGB)), plt.title(
        'Roi'), plt.axis('off')

    plt.show()

    cv.waitKey(0)

    cv.destroyAllWindows()


if __name__ == '__main__':
    main()

demo_11_arithmetic_op

四、二值化

4.1 普通

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


max_value = 255
max_type = 4
max_binary_value = 255
trackbar_type = 'Type'
trackbar_value = 'Value'
window_name = 'Threshold Demo'


def callback(val):
    # 0: Binary                         给定threshold_value,大于它为255,小于为0
    # 1: Binary Inverted                给定threshold_value,大于它为0,小于为255
    # 2: Threshold Truncated            给定threshold_value,大于它为threshold_value,小于则不变
    # 3: Threshold to Zero              给定threshold_value,大于它不变,小于则为0
    # 4: Threshold to Zero Inverted     给定threshold_value,大于它为0,小于则不变
    threshold_type = cv.getTrackbarPos(trackbar_type, window_name)
    threshold_value = cv.getTrackbarPos(trackbar_value, window_name)
    _, dst = cv.threshold(img_gray, threshold_value,
                          max_binary_value, threshold_type)
    cv.imshow(window_name, dst)


def main():

    global img_gray
    img_gray = cv.imread('lena.png', cv.IMREAD_GRAYSCALE)

    cv.namedWindow(window_name)
    cv.resizeWindow(window_name, 512, 512)

    cv.createTrackbar(trackbar_type, window_name, 0, max_type, callback)
    cv.createTrackbar(trackbar_value, window_name, 0, max_value, callback)

    cv.waitKey(0)

    cv.destroyAllWindows()


if __name__ == '__main__':
    main()

demo_12_threshold

4.2 自适应

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


def main():

    img = cv.imread('sudoku.png', cv.IMREAD_GRAYSCALE)
    assert img is not None, "file could not be read, check with os.path.exists()"
    img = cv.medianBlur(img, 5)

    ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)

    #  每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的
    #  THRESH_BINARY      ===>    dst(x, y) = maxValue if src(x, y) > T(x, y) else 0
    #  THRESH_BINARY_INV  ===>    dst(x, y) = 0 if src(x, y) > T(x, y) else maxValue
    #  maxValue 非零值
    #  adaptiveMethod 自适应算法T
    #        1. cv.ADAPTIVE_THRESH_MEAN_C       计算邻域的均值 再减C
    #        2. cv.ADAPTIVE_THRESH_GAUSSIAN_C   计算邻域的高斯加权和,再减C
    #  thresholdType 必须是 cv.THRESH_BINARY 或 cv.THRESH_BINARY_INV
    #  blockSize   邻域大小 blockSize * blockSize, 一般用3,5,7等等
    #  C  要减去的值
    th2 = cv.adaptiveThreshold(img, maxValue=255, adaptiveMethod=cv.ADAPTIVE_THRESH_MEAN_C,
                               thresholdType=cv.THRESH_BINARY, blockSize=11, C=2)
    th3 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,
                               cv.THRESH_BINARY, 11, 2)

    titles = ['Original Image', 'Global Thresholding (v = 127)',
              'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
    images = [img, th1, th2, th3]

    for i in range(4):
        plt.subplot(2, 2, i+1), plt.imshow(images[i], 'gray')
        plt.title(titles[i])
        plt.xticks([]), plt.yticks([])
    plt.show()


if __name__ == '__main__':
    main()

demo_13_adaptive_threshold

4.3 Otsu

在使用 threshold 方法阈值设置中,我们可以使用任意选择的值作为阈值。相比之下,Otsu 二值化不需要手动选择一个值,可以直接设为0

考虑一个只有两个不同图像值的图像(双峰图像),其中直方图将只由两个峰组成。一个很好的阈值应该是在这两个值的中间值。

Otsu 从图像直方图中确定一个最优的全局阈值。该算法找到最优阈值,并作为第一个输出返回。

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


def main():

    img = cv.imread('southeast.jpg', cv.IMREAD_GRAYSCALE)
    assert img is not None, "file could not be read, check with os.path.exists()"

    # global thresholding
    ret1, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)

    # Otsu's thresholding
    ret2, th2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)

    # Otsu's thresholding after Gaussian filtering
    blur = cv.GaussianBlur(img, (7, 7), 0)
    ret3, th3 = cv.threshold(blur, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)

    # plot all the images and their histograms
    images = [img, 0, th1,
              img, 0, th2,
              blur, 0, th3]
    titles = ['Original Noisy Image', 'Histogram', 'Global Thresholding (v=127)',
              'Original Noisy Image', 'Histogram', "Otsu's Thresholding",
              'Gaussian filtered Image', 'Histogram', "Otsu's Thresholding"]

    for i in range(3):
        plt.subplot(3, 3, i*3+1), plt.imshow(images[i*3], 'gray')
        plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
        plt.subplot(3, 3, i*3+2), plt.hist(images[i*3].ravel(), 256)
        plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
        plt.subplot(3, 3, i*3+3), plt.imshow(images[i*3+2], 'gray')
        plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
    plt.show()


if __name__ == '__main__':
    main()

demo_14_otsu_threshold

参考

  1. https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html

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

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

相关文章

PS入门|蒙版到底是个什么样的功能?看完就明白了

前言 前段时间一直说蒙版蒙版什么的,很多小伙伴估计都听得一头雾水。 抠个图要加蒙版,调个色要加蒙版。 小白感觉这个蒙版就像调味剂一样,啥都需要加一个蒙版。 动不动就加个蒙版,究竟是干啥用的? 今天咱们就深入来…

【深度学习-第5篇】使用Python快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例(使用pytorch框架)

在之前的文章中介绍了CNN的图解入门,CNN的MATLAB分类实现,CNN的MATLAB回归实现。 卷积神经网络(Convolutional Neural Networ,简称CNN)是一种广泛应用于图像识别领域的深度学习算法。它通过模拟人类视觉系统的层次结构,可以自动提…

【linux】软件工具安装 + vim 和 gcc 使用(上)

目录 1. linux 安装软件途径 2. rzsz 命令 3. vim 和 gcc 使用 a. vim的基本概念 b. 命令模式下的指令 c. 底行模式下的指令 1. linux 安装软件途径 源代码安装rpm安装 -- linux安装包yum安装(最好,可以解决安装源,安装版本&#xff0…

实战 | 无视杀软使用远控工具进行横向移动Tips

实战 | 无视杀软使用远控工具进行横向移动Tips。 在有杀软拦截,CS无法上线的情况下,经常用到todesk和向日葵这两个远控工具进行横向移动。不过这两个工具现在好像不怎么好用了。不过无所谓,用其他的就是了,听说最近GotoHTTP很火&…

手拉手安装Kafka2.13发送和消费消息

Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 Kafka启动方式有Zookeeper和Kraft,两种方式只能选择其中一种启动,不能同时使用。 Kafka下载https://downloads.apache.org/kafka/3.7.0/kafka_2.…

四川易点慧电子商务抖音小店:安全正规,购物新选择

在当今互联网高速发展的时代,电子商务已经成为人们日常购物的重要组成部分。四川易点慧电子商务抖音小店作为新兴的电商平台,凭借其安全正规的经营理念和便捷高效的购物体验,正逐渐赢得消费者的信赖和喜爱。 一、平台背景实力雄厚 四川易点慧…

【Linux系统化学习】线程控制

目录 前言 POSIX线程库 线程控制 创建线程 线程终止 pthread_exit()函数 pthread_cancel()函数(会在下面线程等待部分详解) 线程等待 pthread_join()函数 获取线程退出码 分离线程 线程取消(pthread_cancel()函数) 线程ID及进程…

Scikit-Learn支持向量机分类

Scikit-Learn 支持向量机分类 1、支持向量机(SVM)1.1、SVM概述1.2、SVM原理1.3、SVM的损失函数1.4、支持向量机分类的优缺点 2、Scikit-Learn支持向量机分类2.1、Scikit-Learn支持向量机分类API2.2、支持向量机分类初体验(手写数字识别&#…

【工具-PyCharm】

工具-PyCharm ■ PyCharm-简介■ PyCharm-安装■ PyCharm-使用■ 修改主题■ 设置字体■ 代码模板■ 解释器配置■ 文件默认编码■ 快捷键■ 折叠■ 移动■ 注释■ 编辑■ 删除■ 查看■ 缩进■ 替换 ■ PyCharm-简介 官方下载地址 Professional:专业版&#xff0…

头脑风暴法的四个原则,设计师必看!

俗话说 “三个臭皮匠超越诸葛亮”,这在工作场景中也是如此。最常见的工作场景是会议。会议的目的很多,如工作报告、产品宣传等。头脑风暴是一种工作会议。其目的是集思广益,充分发挥团队的智慧。有效的头脑风暴不仅考验组织者的会议控制能力&…

【前端Vue】Vue3+Pinia小兔鲜电商项目第6篇:整体认识和路由配置,本资源由 收集整理【附代码文档】

Vue3ElementPlusPinia开发小兔鲜电商项目完整教程(附代码资料)主要内容讲述:认识Vue3,使用create-vue搭建Vue3项目1. Vue3组合式API体验,2. Vue3更多的优势,1. 认识create-vue,2. 使用create-vue创建项目,1. setup选项的写法和执行…

【机器学习-17】数据变换---小波变换特征提取及应用案列介绍

引言 在机器学习领域,数据变换是一种常见且重要的预处理步骤。通过对原始数据进行变换,我们可以提取出更有意义的特征,提高模型的性能。在众多数据变换方法中,小波变换是一种非常有效的方法,尤其适用于处理非平稳信号和…

实战解析:SpringBoot接口防抖机制与防重复提交技巧

目录 前言 啥是防抖 思路解析 哪一类接口需要防抖? 如何确定接口是重复的? 分布式部署下如何做接口防抖? 使用共享缓存 使用分布式锁 Spring Boot与Redis深度整合入口:实战指南 具体实现 请求锁 唯一key生成 重复提交判断 Red…

scipy.sparse.csr_matrix 中的 indptr indices data

# ------------------------------------------------------------------------------- # Description: 分析理解 scipy.sparse.csr_matrix 中的 indptr & indices & data # Reference: https://blog.csdn.net/bymaymay/article/details/81389722 # Author: Sophia…

Win 进入桌面黑屏,只有鼠标

大家好,我叫秋意零。 今天,遇到一个同事电脑进入桌面黑屏,只有鼠标。经过询问沟通,说是 Windows 突然进行了自动更新,更新之后桌面就黑了屏。经过查询是一个桌面进程没启动才会导致桌面黑屏。首先分两种情况&#xff0…

STL Array、ForwardList源码剖析

STL Array、ForwardList源码剖析 参考文章: https://blog.csdn.net/weixin_45389639/article/details/121618243 array 源代码 template<typename _Tp,std::size_t _Nm> struct array {typedef _Tp value_type;typedef _Tp* pointer;typedef value_type* iterator;// Su…

【看不懂命令行、.yaml?】Hydra 库极速入门

Hydra 是一个开源的 Python 框架&#xff0c;可以简化研究和其他复杂应用程序的开发。其核心功能是通过组合动态创建层次化的配置&#xff0c;并可以通过配置文件和命令行进行覆盖。Hydra 的名字来源于它能够运行多个类似的作业 - 就像一个多头的水怪一样。 主要特性: 从多个…

首发!Llama3纯本地部署攻略!中文方法!

引言 llama3在4月19日刚刚发布&#xff0c;官方的对比结果中在开源模型中堪称世界第一&#xff0c;整好周六日有时间&#xff0c;在魔搭社区上测试一下 一、启动环境 登录魔搭社区&#xff0c;到自己的机器资源&#xff0c;可以看到&#xff0c;可选的机器配置&#xff0c; …

YOLOv9改进策略 | Conv篇 | 利用 Haar 小波的下采样HWD替换传统下采样(改变YOLO传统的Conv下采样)

一、本文介绍 本文给大家带来的改进机制是Haar 小波的下采样HWD替换传统下采样&#xff08;改变YOLO传统的Conv下采样&#xff09;在小波变换中&#xff0c;Haar小波作为一种基本的小波函数&#xff0c;用于将图像数据分解为多个层次的近似和细节信息&#xff0c;这是一种多分…

什么是自动化测试?如何做自动化测试?

前面介绍了功能测试和接口测试&#xff0c;在介绍接口测试时提到了实现API自动化。那具体什么是自动化&#xff0c;为什么要做自动化&#xff0c;这里我们集中总结。 一. 什么是自动化&#xff1f; 顾名思义&#xff0c;自动化测试是相对人工测试而言的&#xff0c;它是指把人…