图像JPEG压缩(附python代码)

news2024/11/23 19:38:05

JPEG压缩是一种有损压缩技术,常用于数字图像。它通过减少图像文件大小来实现压缩,但会造成一定程度的图像质量损失。

目录

  • 一、JPEG压缩
    • 1.1 JPEG压缩原理
    • 1.2 JPEG压缩优点
    • 1.3 JPEG压缩缺点
  • 二、图像退化中加入JPEG压缩
    • 2.1 优势
      • 2.1.1 更逼真的模拟
      • 2.1.2 提高效率
      • 2.1.3 简化模型
    • 2.2 缺点
    • 2.3 加入 JPEG 压缩模拟的具体示例
      • 2.3.1 模拟镜头模糊
      • 2.3.2 模拟大气散射
      • 2.3.3 模拟压缩伪影
  • 三、代码
    • 3.1 cv2.imencode库和cv2.imdecode库
      • 3.1.1 函数原型
      • 3.1.2 示例代码
    • 3.2 DiffJPEG压缩
      • 3.2.1 参数修改
      • 3.2.2 代码
  • 四、压缩效果
  • 五、总结

一、JPEG压缩

1.1 JPEG压缩原理

JPEG压缩的工作原理是利用人眼的视觉特性,对图像进行离散余弦变换和量化。简单来说,就是将图像分成一个个小的方块,然后分析每个方块的亮度和颜色信息。人眼对亮度变化更敏感,对颜色变化的敏感度较低,因此JPEG压缩会保留更多的亮度信息,而舍弃一些颜色信息。

JPEG压缩的压缩程度可以通过压缩率来控制。压缩率越高,图像文件越小,但图像质量也会越差。一般来说,压缩率在70%到80%之间是比较合适的,既能大幅减小文件大小,又能保持较好的图像质量。

1.2 JPEG压缩优点

可以大幅减小图像文件大小,节省存储空间和传输带宽。

压缩后的图像仍然保持较好的视觉质量。

广泛支持,几乎所有图像编辑软件和数码设备都支持JPEG格式。

1.3 JPEG压缩缺点

压缩过程会造成一定程度的图像质量损失,特别是高压缩率下更加明显。

不适用于需要保留原始图像信息的场景,例如医学图像、印刷图像等。

二、图像退化中加入JPEG压缩

2.1 优势

在模拟图像退化过程中加入JPEG压缩,好处见下:

2.1.1 更逼真的模拟

JPEG 压缩会引入块效应、伪影和瑕疵等痕迹,这些痕迹与现实世界中的图像退化现象(例如,镜头模糊、大气散射、压缩伪影等)相似。因此,在模拟图像退化过程中加入 JPEG 压缩可以使模拟结果更加逼真。

2.1.2 提高效率

JPEG 压缩可以显著减小图像文件大小。这在处理大量图像数据时尤其有益,因为它可以节省存储空间和计算资源。

2.1.3 简化模型

JPEG 压缩引入的块效应和伪影可以简化图像退化模型。例如,在模拟运动模糊时,可以先对图像进行 JPEG 压缩,然后再应用运动模糊模型。这样可以避免在运动模糊模型中显式地模拟 JPEG 压缩引起的块效应和伪影。

2.2 缺点

在模拟图像退化过程中加入 JPEG 压缩也有一些潜在的缺点:

可能引入额外的误差: JPEG 压缩本身会造成一定的图像质量损失。如果在模拟图像退化过程中加入 JPEG 压缩,可能会进一步降低图像质量。

可能使模型更难解释: JPEG 压缩引入的块效应和伪影会使图像退化模型更加复杂,从而更难理解和解释。

2.3 加入 JPEG 压缩模拟的具体示例

2.3.1 模拟镜头模糊

镜头模糊会导致图像出现一定的模糊和失真。为了模拟镜头模糊,可以先对图像进行 JPEG 压缩,然后再应用高斯滤波或其他模糊滤波器。

2.3.2 模拟大气散射

大气散射会导致图像出现一定的朦胧和色彩失真。为了模拟大气散射,可以先对图像进行 JPEG 压缩,然后再降低图像的对比度和饱和度。

2.3.3 模拟压缩伪影

除了 JPEG 压缩之外,还有其他类型的图像压缩,例如 PNG 和 GIF 压缩。这些压缩格式也会引入不同的伪影。为了模拟其他类型的压缩伪影,可以先对图像进行相应的压缩,然后再进行其他类型的退化模拟。

三、代码

3.1 cv2.imencode库和cv2.imdecode库

cv2.imencode() 和 cv2.imdecode() 都是 OpenCV 库中用于处理图像编码和解码的函数。

cv2.imencode() 用于将图像编码为特定格式的字节流。它通常用于将图像转换为 JPEG 或 PNG 格式并将其保存到内存中。

3.1.1 函数原型

cv2.imencode(ext, img, [params]) -> (retval, buf)

cv2.imencode()参数说明:

ext: 要使用的图像格式的后缀,例如 ‘jpg’ 或 ‘png’。

img: 要编码的图像。

params: 可选参数,用于控制编码过程。例如,对于 JPEG 格式,可以使用 params 参数来控制压缩质量。

cv2.imdecode(buf, flags) -> img

cv2.imdecode()参数说明:

buf: 要解码的字节流。
flags: 可选参数,用于指定图像的色彩空间。例如,cv2.IMREAD_COLOR 表示使用彩色模式解码图像,cv2.IMREAD_GRAYSCALE 表示使用灰度模式解码图像。

3.1.2 示例代码

import cv2

img_gt = cv2.imread('Images/Visible_Images/1.jpg')

encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 20]        # 设置JPEG图像的质量参数为20,参数可以自定义调整
_, encimg = cv2.imencode('.jpg', img_gt, encode_param)   # 以JPEG格式进行编码
img_lq = np.float32(cv2.imdecode(encimg, 1))            # 解码编码后的图像,并将其转换为浮点类型
cv2.imwrite('Result/DiffJpeg/CV_Result/cv2_JPEG_20.png', img_lq)     # 将解码后的图像保存为’cv2_JPEG_20.png’        

3.2 DiffJPEG压缩

DiffJPEG压缩是基于pythorch实现的,压缩图像与OpecnCV包压缩的图像略有不同。

3.2.1 参数修改

使用代码,只需要修改下面参数即可:
在这里插入图片描述

3.2.2 代码


import itertools
import numpy as np
import torch
import torch.nn as nn
from torch.nn import functional as F

# ------------------------ utils ------------------------#
y_table = np.array(
    [[16, 11, 10, 16, 24, 40, 51, 61], [12, 12, 14, 19, 26, 58, 60, 55], [14, 13, 16, 24, 40, 57, 69, 56],
     [14, 17, 22, 29, 51, 87, 80, 62], [18, 22, 37, 56, 68, 109, 103, 77], [24, 35, 55, 64, 81, 104, 113, 92],
     [49, 64, 78, 87, 103, 121, 120, 101], [72, 92, 95, 98, 112, 100, 103, 99]],
    dtype=np.float32).T
y_table = nn.Parameter(torch.from_numpy(y_table))
c_table = np.empty((8, 8), dtype=np.float32)
c_table.fill(99)
c_table[:4, :4] = np.array([[17, 18, 24, 47], [18, 21, 26, 66], [24, 26, 56, 99], [47, 66, 99, 99]]).T
c_table = nn.Parameter(torch.from_numpy(c_table))


def diff_round(x):
    """ Differentiable rounding function
    """
    return torch.round(x) + (x - torch.round(x))**3


def quality_to_factor(quality):
    """ Calculate factor corresponding to quality

    Args:
        quality(float): Quality for jpeg compression.

    Returns:
        float: Compression factor.
    """
    if quality < 50:
        quality = 5000. / quality
    else:
        quality = 200. - quality * 2
    return quality / 100.


# ------------------------ compression ------------------------#
class RGB2YCbCrJpeg(nn.Module):
    """ Converts RGB image to YCbCr
    """

    def __init__(self):
        super(RGB2YCbCrJpeg, self).__init__()
        matrix = np.array([[0.299, 0.587, 0.114], [-0.168736, -0.331264, 0.5], [0.5, -0.418688, -0.081312]],
                          dtype=np.float32).T
        self.shift = nn.Parameter(torch.tensor([0., 128., 128.]))
        self.matrix = nn.Parameter(torch.from_numpy(matrix))

    def forward(self, image):
        """
        Args:
            image(Tensor): batch x 3 x height x width

        Returns:
            Tensor: batch x height x width x 3
        """
        image = image.permute(0, 2, 3, 1)
        result = torch.tensordot(image, self.matrix, dims=1) + self.shift
        return result.view(image.shape)


class ChromaSubsampling(nn.Module):
    """ Chroma subsampling on CbCr channels
    """

    def __init__(self):
        super(ChromaSubsampling, self).__init__()

    def forward(self, image):
        """
        Args:
            image(tensor): batch x height x width x 3

        Returns:
            y(tensor): batch x height x width
            cb(tensor): batch x height/2 x width/2
            cr(tensor): batch x height/2 x width/2
        """
        image_2 = image.permute(0, 3, 1, 2).clone()
        cb = F.avg_pool2d(image_2[:, 1, :, :].unsqueeze(1), kernel_size=2, stride=(2, 2), count_include_pad=False)
        cr = F.avg_pool2d(image_2[:, 2, :, :].unsqueeze(1), kernel_size=2, stride=(2, 2), count_include_pad=False)
        cb = cb.permute(0, 2, 3, 1)
        cr = cr.permute(0, 2, 3, 1)
        return image[:, :, :, 0], cb.squeeze(3), cr.squeeze(3)


class BlockSplitting(nn.Module):
    """ Splitting image into patches
    """

    def __init__(self):
        super(BlockSplitting, self).__init__()
        self.k = 8

    def forward(self, image):
        """
        Args:
            image(tensor): batch x height x width

        Returns:
            Tensor:  batch x h*w/64 x h x w
        """
        height, _ = image.shape[1:3]
        batch_size = image.shape[0]
        image_reshaped = image.view(batch_size, height // self.k, self.k, -1, self.k)
        image_transposed = image_reshaped.permute(0, 1, 3, 2, 4)
        return image_transposed.contiguous().view(batch_size, -1, self.k, self.k)


class DCT8x8(nn.Module):
    """ Discrete Cosine Transformation
    """

    def __init__(self):
        super(DCT8x8, self).__init__()
        tensor = np.zeros((8, 8, 8, 8), dtype=np.float32)
        for x, y, u, v in itertools.product(range(8), repeat=4):
            tensor[x, y, u, v] = np.cos((2 * x + 1) * u * np.pi / 16) * np.cos((2 * y + 1) * v * np.pi / 16)
        alpha = np.array([1. / np.sqrt(2)] + [1] * 7)
        self.tensor = nn.Parameter(torch.from_numpy(tensor).float())
        self.scale = nn.Parameter(torch.from_numpy(np.outer(alpha, alpha) * 0.25).float())

    def forward(self, image):
        """
        Args:
            image(tensor): batch x height x width

        Returns:
            Tensor: batch x height x width
        """
        image = image - 128
        result = self.scale * torch.tensordot(image, self.tensor, dims=2)
        result.view(image.shape)
        return result


class YQuantize(nn.Module):
    """ JPEG Quantization for Y channel

    Args:
        rounding(function): rounding function to use
    """

    def __init__(self, rounding):
        super(YQuantize, self).__init__()
        self.rounding = rounding
        self.y_table = y_table

    def forward(self, image, factor=1):
        """
        Args:
            image(tensor): batch x height x width

        Returns:
            Tensor: batch x height x width
        """
        if isinstance(factor, (int, float)):
            image = image.float() / (self.y_table * factor)
        else:
            b = factor.size(0)
            table = self.y_table.expand(b, 1, 8, 8) * factor.view(b, 1, 1, 1)
            image = image.float() / table
        image = self.rounding(image)
        return image


class CQuantize(nn.Module):
    """ JPEG Quantization for CbCr channels

    Args:
        rounding(function): rounding function to use
    """

    def __init__(self, rounding):
        super(CQuantize, self).__init__()
        self.rounding = rounding
        self.c_table = c_table

    def forward(self, image, factor=1):
        """
        Args:
            image(tensor): batch x height x width

        Returns:
            Tensor: batch x height x width
        """
        if isinstance(factor, (int, float)):
            image = image.float() / (self.c_table * factor)
        else:
            b = factor.size(0)
            table = self.c_table.expand(b, 1, 8, 8) * factor.view(b, 1, 1, 1)
            image = image.float() / table
        image = self.rounding(image)
        return image


class CompressJpeg(nn.Module):
    """Full JPEG compression algorithm

    Args:
        rounding(function): rounding function to use
    """

    def __init__(self, rounding=torch.round):
        super(CompressJpeg, self).__init__()
        self.l1 = nn.Sequential(RGB2YCbCrJpeg(), ChromaSubsampling())
        self.l2 = nn.Sequential(BlockSplitting(), DCT8x8())
        self.c_quantize = CQuantize(rounding=rounding)
        self.y_quantize = YQuantize(rounding=rounding)

    def forward(self, image, factor=1):
        """
        Args:
            image(tensor): batch x 3 x height x width

        Returns:
            dict(tensor): Compressed tensor with batch x h*w/64 x 8 x 8.
        """
        y, cb, cr = self.l1(image * 255)
        components = {'y': y, 'cb': cb, 'cr': cr}
        for k in components.keys():
            comp = self.l2(components[k])
            if k in ('cb', 'cr'):
                comp = self.c_quantize(comp, factor=factor)
            else:
                comp = self.y_quantize(comp, factor=factor)

            components[k] = comp

        return components['y'], components['cb'], components['cr']


# ------------------------ decompression ------------------------#


class YDequantize(nn.Module):
    """Dequantize Y channel
    """

    def __init__(self):
        super(YDequantize, self).__init__()
        self.y_table = y_table

    def forward(self, image, factor=1):
        """
        Args:
            image(tensor): batch x height x width

        Returns:
            Tensor: batch x height x width
        """
        if isinstance(factor, (int, float)):
            out = image * (self.y_table * factor)
        else:
            b = factor.size(0)
            table = self.y_table.expand(b, 1, 8, 8) * factor.view(b, 1, 1, 1)
            out = image * table
        return out


class CDequantize(nn.Module):
    """Dequantize CbCr channel
    """

    def __init__(self):
        super(CDequantize, self).__init__()
        self.c_table = c_table

    def forward(self, image, factor=1):
        """
        Args:
            image(tensor): batch x height x width

        Returns:
            Tensor: batch x height x width
        """
        if isinstance(factor, (int, float)):
            out = image * (self.c_table * factor)
        else:
            b = factor.size(0)
            table = self.c_table.expand(b, 1, 8, 8) * factor.view(b, 1, 1, 1)
            out = image * table
        return out


class iDCT8x8(nn.Module):
    """Inverse discrete Cosine Transformation
    """

    def __init__(self):
        super(iDCT8x8, self).__init__()
        alpha = np.array([1. / np.sqrt(2)] + [1] * 7)
        self.alpha = nn.Parameter(torch.from_numpy(np.outer(alpha, alpha)).float())
        tensor = np.zeros((8, 8, 8, 8), dtype=np.float32)
        for x, y, u, v in itertools.product(range(8), repeat=4):
            tensor[x, y, u, v] = np.cos((2 * u + 1) * x * np.pi / 16) * np.cos((2 * v + 1) * y * np.pi / 16)
        self.tensor = nn.Parameter(torch.from_numpy(tensor).float())

    def forward(self, image):
        """
        Args:
            image(tensor): batch x height x width

        Returns:
            Tensor: batch x height x width
        """
        image = image * self.alpha
        result = 0.25 * torch.tensordot(image, self.tensor, dims=2) + 128
        result.view(image.shape)
        return result


class BlockMerging(nn.Module):
    """Merge patches into image
    """

    def __init__(self):
        super(BlockMerging, self).__init__()

    def forward(self, patches, height, width):
        """
        Args:
            patches(tensor) batch x height*width/64, height x width
            height(int)
            width(int)

        Returns:
            Tensor: batch x height x width
        """
        k = 8
        batch_size = patches.shape[0]
        image_reshaped = patches.view(batch_size, height // k, width // k, k, k)
        image_transposed = image_reshaped.permute(0, 1, 3, 2, 4)
        return image_transposed.contiguous().view(batch_size, height, width)


class ChromaUpsampling(nn.Module):
    """Upsample chroma layers
    """

    def __init__(self):
        super(ChromaUpsampling, self).__init__()

    def forward(self, y, cb, cr):
        """
        Args:
            y(tensor): y channel image
            cb(tensor): cb channel
            cr(tensor): cr channel

        Returns:
            Tensor: batch x height x width x 3
        """

        def repeat(x, k=2):
            height, width = x.shape[1:3]
            x = x.unsqueeze(-1)
            x = x.repeat(1, 1, k, k)
            x = x.view(-1, height * k, width * k)
            return x

        cb = repeat(cb)
        cr = repeat(cr)
        return torch.cat([y.unsqueeze(3), cb.unsqueeze(3), cr.unsqueeze(3)], dim=3)


class YCbCr2RGBJpeg(nn.Module):
    """Converts YCbCr image to RGB JPEG
    """

    def __init__(self):
        super(YCbCr2RGBJpeg, self).__init__()

        matrix = np.array([[1., 0., 1.402], [1, -0.344136, -0.714136], [1, 1.772, 0]], dtype=np.float32).T
        self.shift = nn.Parameter(torch.tensor([0, -128., -128.]))
        self.matrix = nn.Parameter(torch.from_numpy(matrix))

    def forward(self, image):
        """
        Args:
            image(tensor): batch x height x width x 3

        Returns:
            Tensor: batch x 3 x height x width
        """
        result = torch.tensordot(image + self.shift, self.matrix, dims=1)
        return result.view(image.shape).permute(0, 3, 1, 2)


class DeCompressJpeg(nn.Module):
    """Full JPEG decompression algorithm

    Args:
        rounding(function): rounding function to use
    """

    def __init__(self, rounding=torch.round):
        super(DeCompressJpeg, self).__init__()
        self.c_dequantize = CDequantize()
        self.y_dequantize = YDequantize()
        self.idct = iDCT8x8()
        self.merging = BlockMerging()
        self.chroma = ChromaUpsampling()
        self.colors = YCbCr2RGBJpeg()

    def forward(self, y, cb, cr, imgh, imgw, factor=1):
        """
        Args:
            compressed(dict(tensor)): batch x h*w/64 x 8 x 8
            imgh(int)
            imgw(int)
            factor(float)

        Returns:
            Tensor: batch x 3 x height x width
        """
        components = {'y': y, 'cb': cb, 'cr': cr}
        for k in components.keys():
            if k in ('cb', 'cr'):
                comp = self.c_dequantize(components[k], factor=factor)
                height, width = int(imgh / 2), int(imgw / 2)
            else:
                comp = self.y_dequantize(components[k], factor=factor)
                height, width = imgh, imgw
            comp = self.idct(comp)
            components[k] = self.merging(comp, height, width)
            #
        image = self.chroma(components['y'], components['cb'], components['cr'])
        image = self.colors(image)

        image = torch.min(255 * torch.ones_like(image), torch.max(torch.zeros_like(image), image))
        return image / 255


# ------------------------ main DiffJPEG ------------------------ #


class DiffJPEG(nn.Module):
    """This JPEG algorithm result is slightly different from cv2.
    DiffJPEG supports batch processing.

    Args:
        differentiable(bool): If True, uses custom differentiable rounding function, if False, uses standard torch.round
    """

    def __init__(self, differentiable=True):
        super(DiffJPEG, self).__init__()
        if differentiable:
            rounding = diff_round
        else:
            rounding = torch.round

        self.compress = CompressJpeg(rounding=rounding)
        self.decompress = DeCompressJpeg(rounding=rounding)

    def forward(self, x, quality):
        """
        Args:
            x (Tensor): Input image, bchw, rgb, [0, 1]
            quality(float): Quality factor for jpeg compression scheme.
        """
        factor = quality
        if isinstance(factor, (int, float)):
            factor = quality_to_factor(factor)
        else:
            for i in range(factor.size(0)):
                factor[i] = quality_to_factor(factor[i])
        h, w = x.size()[-2:]
        h_pad, w_pad = 0, 0
        # why should use 16
        if h % 16 != 0:
            h_pad = 16 - h % 16
        if w % 16 != 0:
            w_pad = 16 - w % 16
        x = F.pad(x, (0, w_pad, 0, h_pad), mode='constant', value=0)

        y, cb, cr = self.compress(x, factor=factor)
        recovered = self.decompress(y, cb, cr, (h + h_pad), (w + w_pad), factor=factor)
        recovered = recovered[:, :, 0:h, 0:w]
        return recovered


if __name__ == '__main__':
    import cv2

    from basicsr.utils import img2tensor, tensor2img                 # 从basicsr.utils模块导入img2tensor和tensor2img函数,这两个函数分别用于将图像转换为张量和将张量转换为图像。

    img_gt = cv2.imread('Images/Visible_Images/1.jpg') / 255.         # 读取名为’test.png’的图像文件,并将其像素值归一化到0-1之间
    # -------------- DiffJPEG -------------- #
    jpeger = DiffJPEG(differentiable=False).cuda()         # 创建一个DiffJPEG对象,这是一个用于JPEG编码和解码的类,differentiable=False表示该对象不可微分
    img_gt = img2tensor(img_gt)                            # 将图像转换为张量
    img_gt = torch.stack([img_gt, img_gt]).cuda()          # 创建一个新的张量,该张量由两个img_gt张量堆叠而成,并将其移动到GPU上。
    quality = img_gt.new_tensor([10,90])                  # 创建一个新的张量,该张量包含两个元素20和40,这两个元素表示JPEG图像的质量参数。
    out = jpeger(img_gt, quality=quality)                  # 使用jpeger对象对图像进行JPEG编码

    cv2.imwrite('Result/DiffJpeg/DiffJpeg_Result/pt_JPEG_10.png', tensor2img(out[0]))
    cv2.imwrite('Result/DiffJpeg/DiffJpeg_Result/pt_JPEG_90.png', tensor2img(out[1]))

四、压缩效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、总结

以上就是图像JPEG压缩的两种方法,OpenCV包中的压缩方法使用不同的软件包生成的结果有差异。学者自行调整质量参数尝试。

总结不易,多多支持,谢谢!

感谢您阅读到最后!关注公众号「视觉研坊」,获取干货教程、实战案例、技术解答、行业资讯!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OceanMind海睿思助力企业“数据入表”经济利益流入与生命周期管理

通过多年信息系统的建设与应用&#xff0c;企业积累了大量的数据。同时随着时间的推进&#xff0c;数据规模正以加速度快速增长。从国家到企业&#xff0c;都越来越关注所拥有的数据资源及其蕴含的深厚价值。很多企业已经逐渐认知到数据是重要的战略资源&#xff0c;数据资产化…

Acwing.3999 最大公约数(gcd欧拉函数)

题解 给定两个正整数 a,m&#xff0c;其中 a<m。 请你计算&#xff0c;有多少个小于 m 的非负整数 x满足&#xff1a; gcd(a,m)gcd(ax,m) 输入格式 第一行包含整数 T &#xff0c;表示共有 T 组测试数据。 每组数据占一行&#xff0c;包含两个整数 a,m 。 输出格式 每…

2024年第十四届MathorCup数学应用挑战赛C题解析(更新中)

2024年第十四届MathorCup数学应用挑战赛C题解析&#xff08;更新中&#xff09; 题目题目解析(更新中&#xff09;问题一问题二问题三 题目 C题 物流网络分拣中心货量预测及人员排班电商物流网络在订单履约中由多个环节组成&#xff0c;图1是一个简化的物流 网络示意图。其中&a…

UI自动化测试案例

备注:本文为博主原创文章,未经博主允许禁止转载。如有问题,欢迎指正。 个人笔记(整理不易,有帮助,收藏+点赞+评论,爱你们!!!你的支持是我写作的动力) 笔记目录:笔记本~笔记目录_airtest和selenium那个好用-CSDN博客 个人随笔:工作总结随笔_8、以前工作中都接触过哪…

Ansys Zemax | 如何将光栅数据从Lumerical导入至OpticStudio(下)

附件下载 联系工作人员获取附件 本文介绍了一种使用Ansys Zemax OpticStudio和Lumerical RCWA在整个光学系统中精确仿真1D/2D光栅的静态工作流程。将首先简要介绍方法。然后解释有关如何建立系统的详细信息。 本篇内容将分为上下两部分&#xff0c;上部将首先简要介绍方法工作…

如何处理ubuntu22.04LTS安装过程中出现“Daemons using outdated libraries”提示

Ubuntu 22.04 LTS 中使用命令行升级软件或安装任何新软件时&#xff0c;您可能收到“Daemons using outdated libraries”&#xff0c;“Which services should be restarted?”的提示&#xff0c;提示下面列出备选的重启服务&#xff0c;如下。 使用以下命令&#xff0c;能够…

【C】动态规划 之 多维最大最小路径和

总结一下这类题型的思路&#xff1a; 每一步所求的最优解 上一步的最优解 这一步的情况 1.数字三角形 主要思路&#xff1a; 1.到达每一个位置的最大和等于前一步最大和加上这一位置的值&#xff0c;而前一步要么是从左上下来&#xff0c;要么是从右上下来&#xff0c;这样…

如何应对app应用程序或者网站常见的几种攻击类型

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天&#xff0c;我想和大家聊聊一个我们日常生活中经常遇到的问题——如何应对app或者网站常见的几种攻击类型。随着互联网的普及&#xff0c;app和网站已经成为我们获取信息、交流互动的重要平台。然而&#xff0c;这些平台也时常…

障碍物识别技术赋能盲人独立出行:一场静默的科技革新

作为一名资深记者&#xff0c;我始终关注并报道那些科技如何助力特殊群体克服生活挑战的动人故事。近期&#xff0c;一款叫做蝙蝠避障的应用进入了我的视线&#xff0c;它搭载先进障碍物识别技术以其独特的优势&#xff0c;悄然为视障人士的独立出行带来了显著变革。 “障碍物识…

MXNet安装:专业指南与深度解析

一、引言 MXNet是一个高效且灵活的深度学习框架&#xff0c;它支持多种编程语言和平台&#xff0c;并提供了丰富的深度学习算法和工具。随着深度学习技术的广泛应用&#xff0c;MXNet因其出色的性能和易用性受到了越来越多开发者和研究人员的青睐。本文将详细介绍MXNet的安装过…

基于yolov9来训练人脸检测

YOLOv9是一个在目标检测领域内具有突破性进展的深度学习模型&#xff0c;尤其以其在实时性与准确性上的优秀表现而受到广泛关注。针对人脸检测这一特定任务&#xff0c;YOLOv9通过其架构创新和算法优化提供了强大的支持。 YOLOv9在继承了YOLO系列&#xff08;如YOLOv7、YOLOv8&…

【数据结构与算法】二分查找算法

目录 二分查找算法什么是二分查找算法整数二分法常用算法模板 二分查找算法例题例题一&#xff1a;分巧克力问题例题二&#xff1a;M次方根 二分查找算法 什么是二分查找算法 枚举查找即顺序查找*&#xff0c;实现原理是逐个比较数组 a[0:n-1] 中的元素&#xff0c;直到找到元…

NFT Insider #126:Azuki 创始人将探索使用 AnimeChain 向 NFT 所有者分配版税

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members &#xff08;https://twitter.com/WHALEMembers&#xff09;、BeepCrypto &#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜…

互联网轻量级框架整合之设计模式

反射技术 Java的反射技术能够通过配置类的全限定名、方法和参数完成对象的初始化&#xff0c;甚至反射某些方法&#xff0c;大大的增强了Java的可配置型&#xff0c;这也是Spring IoC的底层原理&#xff0c;Java的反射技术覆盖面很广&#xff0c;包括对象构建、反射方法、注解、…

【Linux杂货铺】文件系统

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 硬盘 &#x1f4c2; 物理结构 &#x1f4c2; 存储结构 &#x1f4c2; CHS定址法 &#x1f4c2; 操作系统对硬盘的管理和抽象 &#x1f4c1; 文件系统 &#x1f4c2; 分区 &#x1f4c2; 分组 &#x1f4c2; inode号 分配…

十分钟到底能不能讲明白ROS到底能做啥

总结 录完视频发现十分钟不能&#xff0c;总共花了20分钟。 提纲&#xff1a; 课程、竞赛、论文Linux、C、Python、Github和ROS关联性强平台-资格和ROS关联性弱速度-成绩路径规划-全局和局部全局-侧重路径长短-找一条最优&#xff08;短&#xff09;的路局部-侧重速度控制-用…

LeetCode-72. 编辑距离【字符串 动态规划】

LeetCode-72. 编辑距离【字符串 动态规划】 题目描述&#xff1a;解题思路一&#xff1a;动规五部曲解题思路二&#xff1a;动态规划【版本二】解题思路三&#xff1a;0 题目描述&#xff1a; 给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最…

【R语言从0到精通】-3-R统计分析(列联表、独立性检验、相关性检验、t检验)

上两次教程集中学习了R语言的基本知识&#xff0c;那么我们很多时候使用R语言是进行统计分析&#xff0c;因此对于生物信息学和统计科学来说&#xff0c;R语言提供了简单优雅的方式进行统计分析。教程参考《Rlearning》 3.1 描述性统计分析 3.1.1 载入数据集及summary函数 我…

安卓一键logo设计工具_V3.6.9.1 高级版

【分析】&#xff1a;LOGO设计软件&#xff0c;可以一键生成无版权的网站LOGO等等。 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码&#xff1a;0b8x

看linux内核启动流程需要的arm汇编学习笔记(二)

文章目录 一、ldr1.地址偏移模式2.变基模式3.标签3.1 访问宏定义3.2 访问一个字符串3.3 访问一个data 二、ldp和stp1.双字节加载2.双字节存储3.双字节存储的后变基模式 三、位操作1. 移位2. 按位操作3. 位段插入4.位段提取5.零计数指令 四、跳转指令1. cmp比较两个数2. cmn负向…