【OpenCV实现图像:用OpenCV图像处理技巧之巧用直方图】

news2024/11/20 8:33:07

文章目录

    • 概要
    • 前置条件
    • 统计数据分析
    • 直方图均衡化原理
    • 小结

概要

图像处理是计算机视觉领域中的重要组成部分,而直方图在图像处理中扮演着关键的角色。如何巧妙地运用OpenCV库中的图像处理技巧,特别是直方图相关的方法,来提高图像质量、改善细节以及调整曝光。
通过对图像的直方图进行分析和调整,能够优化图像的对比度、亮度和色彩平衡,从而使图像更具可视化效果。

直方图是一种统计图,用于表示图像中像素灰度级别的分布情况。在OpenCV中,可以使用直方图来了解图像的整体亮度分布,从而为后续处理提供基础。

OpenCV库中的函数,如cv2.calcHist和cv2.equalizeHist等,对图像的直方图进行均衡化。直方图均衡化是一种有效的方法,通过重新分配像素的强度值,使图像的亮度分布更均匀,提高图像的对比度和细节。

直方图匹配的应用,通过将目标图像的直方图调整到参考图像的直方图,实现两者之间的色彩一致性。这在图像配准和合成中有广泛的应用,提高了图像处理的精度和效果。

在低光照条件下拍摄图像的处理技巧。通过分析图像的直方图,可以采取针对性的方法,提高低光照图像中物体的可见性,改善图像的细节,并校正曝光过度或曝光不足的问题。

前置条件

一般来说,通过合理利用一些直方图的技巧,可以用于提高低光照拍摄图像中物体的可见性,改善图像的细节,以及校正曝光过度或曝光不足的图像。

import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage.exposure import histogram, cumulative_distribution
from skimage import filters
from skimage.color import rgb2hsv, rgb2gray, rgb2yuv
from skimage import color, exposure, transform
from skimage.exposure import histogram, cumulative_distribution

from skimage.io import imread

# Load the image & remove the alpha or opacity channel (transparency)
dark_image = imread('img.png')[:,:,:3]

# Visualize the image
plt.figure(figsize=(10, 10))
plt.title('Original Image: Plasma Ball')
plt.imshow(dark_image)
plt.show()

在这里插入图片描述
上述图像是在光照不足下进行拍摄的,接着我们就来通过控制直方图,来改善我们的视觉效果。

统计数据分析

使用以下代码:


def calc_color_overcast(image):
    # Calculate color overcast for each channel
    red_channel = image[:, :, 0]
    green_channel = image[:, :, 1]
    blue_channel = image[:, :, 2]

    # Create a dataframe to store the results
    channel_stats = pd.DataFrame(columns=['Mean', 'Std', 'Min', 'Median', 
                                          'P_80', 'P_90', 'P_99', 'Max'])

    # Compute and store the statistics for each color channel
    for channel, name in zip([red_channel, green_channel, blue_channel], 
                             ['Red', 'Green', 'Blue']):
        mean = np.mean(channel)
        std = np.std(channel)
        minimum = np.min(channel)
        median = np.median(channel)
        p_80 = np.percentile(channel, 80)
        p_90 = np.percentile(channel, 90)
        p_99 = np.percentile(channel, 99)
        maximum = np.max(channel)

        channel_stats.loc[name] = [mean, std, minimum, median, p_80, p_90, p_99, maximum]

    return channel_stats

完整代码:

import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage.exposure import histogram, cumulative_distribution
from skimage import filters
from skimage.color import rgb2hsv, rgb2gray, rgb2yuv
from skimage import color, exposure, transform
from skimage.exposure import histogram, cumulative_distribution
import pandas as pd

from skimage.io import imread

# Load the image & remove the alpha or opacity channel (transparency)
dark_image = imread('img.png')[:,:,:3]

# Visualize the image
plt.figure(figsize=(10, 10))
plt.title('Original Image: Plasma Ball')
plt.imshow(dark_image)
plt.show()

def calc_color_overcast(image):
    # Calculate color overcast for each channel
    red_channel = image[:, :, 0]
    green_channel = image[:, :, 1]
    blue_channel = image[:, :, 2]

    # Create a dataframe to store the results
    channel_stats = pd.DataFrame(columns=['Mean', 'Std', 'Min', 'Median',
                                          'P_80', 'P_90', 'P_99', 'Max'])

    # Compute and store the statistics for each color channel
    for channel, name in zip([red_channel, green_channel, blue_channel],
                             ['Red', 'Green', 'Blue']):
        mean = np.mean(channel)
        std = np.std(channel)
        minimum = np.min(channel)
        median = np.median(channel)
        p_80 = np.percentile(channel, 80)
        p_90 = np.percentile(channel, 90)
        p_99 = np.percentile(channel, 99)
        maximum = np.max(channel)

        channel_stats.loc[name] = [mean, std, minimum, median, p_80, p_90, p_99, maximum]

    return channel_stats
# 调用函数并传入图像
result_stats = calc_color_overcast(dark_image)

# 打印结果
print(result_stats)

在这里插入图片描述
进而我们可以使用以下代码,来生成上述图像的直方图分布:

# Histogram plot
dark_image_intensity = img_as_ubyte(rgb2gray(dark_image))
freq, bins = histogram(dark_image_intensity)
plt.step(bins, freq*1.0/freq.sum())
plt.xlabel('intensity value')
plt.ylabel('fraction of pixels');
plt.show()  # 添加这一行以显示直方图

得到直方图可视化效果如下:
在这里插入图片描述
通过直方图的观察,可以注意到图像的像素平均强度似乎非常低,这进一步证实了图像的整体暗淡和曝光不足的情况。直方图展示了图像中像素强度值的分布情况,而大多数像素具有较低的强度值。这是有道理的,因为低像素强度值意味着图像中的大多数像素非常暗或呈现黑色。这样的观察有助于定量了解图像的亮度分布,为进一步的图像增强和调整提供了重要的线索。

直方图均衡化原理

直方图均衡化的基本原理是通过线性化图像的累积分布函数(CDF)来提高图像的对比度。实现这一目标的方法是将图像中每个像素的强度值映射到一个新的值,使得新的强度分布更加均匀。

可以通过以下几个步骤实现CDF的线性化:

将图像转换为灰度图:
如果图像不是灰度图,代码会将其转换为灰度图。这是因为直方图均衡化主要应用于灰度图。

计算累积分布函数(CDF):
通过计算图像像素的强度值的累积分布函数,可以了解每个强度值在图像中出现的累积频率。

绘制实际和目标CDF:
使用蓝色实线表示实际的CDF,使用红色实线表示目标CDF。目标CDF是一个线性分布,通过均匀分布来提高对比度。

绘制示例查找表:
绘制一个示例查找表,展示了像素强度值从原始值映射到目标值的过程。

自定义绘图:
对绘图进行自定义,包括设置坐标轴范围、标签和标题等。

import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2hsv, rgb2gray, rgb2yuv
from skimage.exposure import histogram, cumulative_distribution
import pandas as pd
from skimage import img_as_ubyte
from skimage.io import imread

# Load the image & remove the alpha or opacity channel (transparency)
dark_image = imread('img.png')[:,:,:3]

# Visualize the image
plt.figure(figsize=(10, 10))
plt.title('Original Image: Plasma Ball')
plt.imshow(dark_image)
plt.show()

def calc_color_overcast(image):
    # Calculate color overcast for each channel
    red_channel = image[:, :, 0]
    green_channel = image[:, :, 1]
    blue_channel = image[:, :, 2]

    # Create a dataframe to store the results
    channel_stats = pd.DataFrame(columns=['Mean', 'Std', 'Min', 'Median',
                                          'P_80', 'P_90', 'P_99', 'Max'])

    # Compute and store the statistics for each color channel
    for channel, name in zip([red_channel, green_channel, blue_channel],
                             ['Red', 'Green', 'Blue']):
        mean = np.mean(channel)
        std = np.std(channel)
        minimum = np.min(channel)
        median = np.median(channel)
        p_80 = np.percentile(channel, 80)
        p_90 = np.percentile(channel, 90)
        p_99 = np.percentile(channel, 99)
        maximum = np.max(channel)

        channel_stats.loc[name] = [mean, std, minimum, median, p_80, p_90, p_99, maximum]

    return channel_stats


def plot_cdf(image):
    # Convert the image to grayscale if needed
    if len(image.shape) == 3:
        image = rgb2gray(image[:, :, :3])

    # Compute the cumulative distribution function
    intensity = np.round(image * 255).astype(np.uint8)
    freq, bins = cumulative_distribution(intensity)

    # Plot the actual and target CDFs
    target_bins = np.arange(256)
    target_freq = np.linspace(0, 1, len(target_bins))
    plt.step(bins, freq, c='b', label='Actual CDF')
    plt.plot(target_bins, target_freq, c='r', label='Target CDF')

    # Plot an example lookup
    example_intensity = 50
    example_target = np.interp(freq[example_intensity], target_freq, target_bins)
    plt.plot([example_intensity, example_intensity, target_bins[-11], target_bins[-11]],
             [0, freq[example_intensity], freq[example_intensity], 0],
             'k--',
             label=f'Example lookup ({example_intensity} -> {example_target:.0f})')

    # Customize the plot
    plt.legend()
    plt.xlim(0, 255)
    plt.ylim(0, 1)
    plt.xlabel('Intensity Values')
    plt.ylabel('Cumulative Fraction of Pixels')
    plt.title('Cumulative Distribution Function')

    return freq, bins, target_freq, target_bins
# 调用函数并传入图像
result_stats = calc_color_overcast(dark_image)

# 打印结果
print(result_stats)
# Histogram plot
# Histogram plot
dark_image_intensity = img_as_ubyte(rgb2gray(dark_image))
freq, bins = histogram(dark_image_intensity)
plt.step(bins, freq*1.0/freq.sum())
plt.xlabel('intensity value')
plt.ylabel('fraction of pixels')
plt.show()  # 添加这一行以显示直方图

# 调用 plot_cdf 函数并传入图像
plot_cdf(dark_image)
plt.show()  # 添加这一行以显示CDF图形

在这里插入图片描述

直方图均衡化实现结果:

import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage.exposure import histogram, cumulative_distribution, equalize_hist
from skimage import img_as_ubyte
from skimage.io import imread


# Load the image & remove the alpha or opacity channel (transparency)
dark_image = imread('img.png')[:,:,:3]

# Visualize the original image
plt.figure(figsize=(10, 10))
plt.title('Original Image: Plasma Ball')
plt.imshow(dark_image)
plt.show()

# Convert the image to grayscale
gray_image = rgb2gray(dark_image)

# Apply histogram equalization
equalized_image = equalize_hist(gray_image)

# Display the original and equalized images
plt.figure(figsize=(15, 7))
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(gray_image, cmap='gray')

plt.subplot(1, 2, 2)
plt.title('Equalized Image')
plt.imshow(equalized_image, cmap='gray')

plt.show()

在这里插入图片描述

扩展:
上面展示了最基本的直方图操作类型,接着让我们尝试不同类型的CDF技术,看看哪种技术适合给定的图像


# Linear
target_bins = np.arange(256)
# Sigmoid
def sigmoid_cdf(x, a=1):
    return (1 + np.tanh(a * x)) / 2
# Exponential
def exponential_cdf(x, alpha=1):
    return 1 - np.exp(-alpha * x)


# Power
def power_law_cdf(x, alpha=1):
    return x ** alpha
# Other techniques:
def adaptive_histogram_equalization(image, clip_limit=0.03, tile_size=(8, 8)):
    clahe = exposure.equalize_adapthist(
        image, clip_limit=clip_limit, nbins=256, kernel_size=(tile_size[0], tile_size[1]))
    return clahe
def gamma_correction(image, gamma=1.0):
    corrected_image = exposure.adjust_gamma(image, gamma)
    return corrected_image
def contrast_stretching_percentile(image, lower_percentile=5, upper_percentile=95):
    in_range = tuple(np.percentile(image, (lower_percentile, upper_percentile)))
    stretched_image = exposure.rescale_intensity(image, in_range)
    return stretched_image

def unsharp_masking(image, radius=5, amount=1.0):
    blurred_image = filters.gaussian(image, sigma=radius, multichannel=True)
    sharpened_image = (image + (image - blurred_image) * amount).clip(0, 1)
    return sharpened_image

def equalize_hist_rgb(image):
    equalized_image = exposure.equalize_hist(image)
    return equalized_image

def equalize_hist_hsv(image):
    hsv_image = color.rgb2hsv(image[:,:,:3])
    hsv_image[:, :, 2] = exposure.equalize_hist(hsv_image[:, :, 2])
    hsv_adjusted = color.hsv2rgb(hsv_image)
    return hsv_adjusted

def equalize_hist_yuv(image):
    yuv_image = color.rgb2yuv(image[:,:,:3])
    yuv_image[:, :, 0] = exposure.equalize_hist(yuv_image[:, :, 0])
    yuv_adjusted = color.yuv2rgb(yuv_image)
    return yuv_adjusted

使用代码:

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread
from skimage.color import rgb2gray
from skimage.exposure import histogram, cumulative_distribution
from skimage import exposure, color, filters

# Load the image & remove the alpha or opacity channel (transparency)
dark_image = imread('img.png')[:, :, :3]

# Visualize the original image
plt.figure(figsize=(10, 10))
plt.title('Original Image: Plasma Ball')
plt.imshow(dark_image)
plt.show()


# Linear
target_bins = np.arange(256)
# Sigmoid
def sigmoid_cdf(x, a=1):
    return (1 + np.tanh(a * x)) / 2
# Exponential
def exponential_cdf(x, alpha=1):
    return 1 - np.exp(-alpha * x)


# Power
def power_law_cdf(x, alpha=1):
    return x ** alpha
# Other techniques:
def adaptive_histogram_equalization(image, clip_limit=0.03, tile_size=(8, 8)):
    clahe = exposure.equalize_adapthist(
        image, clip_limit=clip_limit, nbins=256, kernel_size=(tile_size[0], tile_size[1]))
    return clahe
def gamma_correction(image, gamma=1.0):
    corrected_image = exposure.adjust_gamma(image, gamma)
    return corrected_image
def contrast_stretching_percentile(image, lower_percentile=5, upper_percentile=95):
    in_range = tuple(np.percentile(image, (lower_percentile, upper_percentile)))
    stretched_image = exposure.rescale_intensity(image, in_range)
    return stretched_image

def unsharp_masking(image, radius=5, amount=1.0):
    blurred_image = filters.gaussian(image, sigma=radius, multichannel=True)
    sharpened_image = (image + (image - blurred_image) * amount).clip(0, 1)
    return sharpened_image

def equalize_hist_rgb(image):
    equalized_image = exposure.equalize_hist(image)
    return equalized_image

def equalize_hist_hsv(image):
    hsv_image = color.rgb2hsv(image[:,:,:3])
    hsv_image[:, :, 2] = exposure.equalize_hist(hsv_image[:, :, 2])
    hsv_adjusted = color.hsv2rgb(hsv_image)
    return hsv_adjusted

def equalize_hist_yuv(image):
    yuv_image = color.rgb2yuv(image[:,:,:3])
    yuv_image[:, :, 0] = exposure.equalize_hist(yuv_image[:, :, 0])
    yuv_adjusted = color.yuv2rgb(yuv_image)
    return yuv_adjusted
def apply_cdf(image, cdf_function, *args, **kwargs):
    # Convert the image to grayscale
    gray_image = rgb2gray(image)

    # Calculate the cumulative distribution function (CDF)
    intensity = np.round(gray_image * 255).astype(np.uint8)
    cdf_values, bins = cumulative_distribution(intensity)

    # Apply the specified CDF function
    transformed_cdf = cdf_function(cdf_values, *args, **kwargs)

    # Map the CDF values back to intensity values
    transformed_intensity = np.interp(intensity, cdf_values, transformed_cdf)

    # Rescale the intensity values to [0, 1]
    transformed_intensity = transformed_intensity / 255.0

    # Apply the transformation to the original image
    transformed_image = image.copy()
    for i in range(3):
        transformed_image[:, :, i] = transformed_intensity

    return transformed_image


# Apply and visualize different CDF techniques
linear_image = apply_cdf(dark_image, lambda x: x)
sigmoid_image = apply_cdf(dark_image, sigmoid_cdf, a=1)
exponential_image = apply_cdf(dark_image, exponential_cdf, alpha=1)
power_law_image = apply_cdf(dark_image, power_law_cdf, alpha=1)
adaptive_hist_eq_image = adaptive_histogram_equalization(dark_image)
gamma_correction_image = gamma_correction(dark_image, gamma=1.5)
contrast_stretch_image = contrast_stretching_percentile(dark_image)
unsharp_mask_image = unsharp_masking(dark_image)
equalized_hist_rgb_image = equalize_hist_rgb(dark_image)
equalized_hist_hsv_image = equalize_hist_hsv(dark_image)
equalized_hist_yuv_image = equalize_hist_yuv(dark_image)

# Visualize the results
plt.figure(figsize=(15, 15))
plt.subplot(4, 4, 1), plt.imshow(linear_image), plt.title('Linear CDF')
plt.subplot(4, 4, 2), plt.imshow(sigmoid_image), plt.title('Sigmoid CDF')
plt.subplot(4, 4, 3), plt.imshow(exponential_image), plt.title('Exponential CDF')
plt.subplot(4, 4, 4), plt.imshow(power_law_image), plt.title('Power Law CDF')
plt.subplot(4, 4, 5), plt.imshow(adaptive_hist_eq_image), plt.title('Adaptive Histogram Equalization')
plt.subplot(4, 4, 6), plt.imshow(gamma_correction_image), plt.title('Gamma Correction')
plt.subplot(4, 4, 7), plt.imshow(contrast_stretch_image), plt.title('Contrast Stretching')
plt.subplot(4, 4, 8), plt.imshow(unsharp_mask_image), plt.title('Unsharp Masking')
plt.subplot(4, 4, 9), plt.imshow(equalized_hist_rgb_image), plt.title('Equalized Histogram (RGB)')
plt.subplot(4, 4, 10), plt.imshow(equalized_hist_hsv_image), plt.title('Equalized Histogram (HSV)')
plt.subplot(4, 4, 11), plt.imshow(equalized_hist_yuv_image), plt.title('Equalized Histogram (YUV)')

plt.tight_layout()
plt.show()

输出结果:
在这里插入图片描述

小结

有多种方法和技术可用于改善RGB图像的可视效果,但其中许多方法都需要手动调整参数。上述输出展示了使用不同直方图操作生成的亮度校正效果。通过观察,发现HSV调整、指数变换、对比度拉伸和unsharp masking的效果都是令人满意的。

HSV调整:
HSV调整涉及将RGB图像转换为HSV颜色空间并修改强度分量。这种技术似乎在提高图像可视化效果方面取得了令人满意的结果。

指数变换:
指数变换用于根据指数函数调整像素强度。这种方法在提高图像整体亮度和视觉吸引力方面表现出色。

对比度拉伸:
对比度拉伸旨在通过拉伸指定百分位范围内的强度值来增强图像对比度。结果表明,这种技术有效地提高了图像的视觉质量。

Unsharp Masking:
Unsharp masking涉及通过减去模糊版本来创建图像的锐化版本。应用unsharp masking似乎增强了图像的细节和边缘

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

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

相关文章

threejs (三) 几何体

定义:用来表示物体的形状,可以定义物体的大小,可以被缩放、旋转和平移 内置几何体: 二维几何体:PlaneGeometry矩形平面、CircleGeometry圆形平面、RingGeometry环形平面、ShapeGeometry二维图形三维几何体&#xff1a…

UI和UX设计师实用高效的设计工具大全

真正专业和优秀的UX设计师不会介意使用哪个工具。因为,只要能力足够,即使条件不同,工具不同,也可以设计出让人眼前一亮的作品。也许,这种理解本身并没有什么大问题。然而,如今,设计师显然有如此…

【汇编语言基础入门】—— 汇编的基础介绍

文章目录 一、机器语言二、汇编语言三、CPU 与 CPU 内存1、CPU 对存储器的读写 四、CPU 的典型构成1、寄存器2、通用寄存器3、物理地址的计算方法4、CS5、DS6、SS SP 一、机器语言 在学习汇编语言之前,我们应该先了解一下什么是机器语言。机器语言是机器指令的集合&…

网络渗透测试(被动扫描)

被动扫描 主要是指的是在目标无法察觉的情况下进行信息搜集。在Google上进行人名的搜素就是一次被动扫描。最经典的被动扫描技术就是"Google Hacking"技术。由于Google退出中国,暂时无法使用。在此介绍三个优秀的信息搜集工具 被动扫描范围 1.企业网络…

Kafka(三)生产者发送消息

文章目录 生产者发送思路自定义序列化类配置生产者参数提升吞吐量 发送消息关闭生产者结语示例源码仓库 生产者发送思路 如何确保消息格式正确的前提下最终一定能发送到Kafka? 这里的实现思路是 ack使用默认的all开启重试在一定时间内重试不成功,则入库&#xff…

基于Python实现,调用百度通用翻译API-详解

概述 在工作上需要各个国家语言的翻译方面很多地方用的上。 获取API权限: 登录百度账号,在个人信息界面,包括修改密码、绑定手机、身份人证等 https://api.fanyi.baidu.com/api/trans/product/desktop?req=developer 百度翻译开放平台 在开发者中心:需要开通个人账号…

13.利用辗转相除法求两个整数的最大公约数和最小公倍数。如96,36

文章目录 前言一、题目描述 二、题目分析 三、解题 前言 本系列为循环结构编程题,点滴成长,一起逆袭。 一、题目描述 利用辗转相除法求两个整数的最大公约数和最小公倍数,如96,36 二、题目分析 最小公倍数(输入的两个数之积)除(它们的最大公约数) 三…

【斗破年番】老婆们见面针锋相对,万蝎门勾结魂殿,大战一触即发

Hello,小伙伴们,我是小郑继续为大家深度解析国漫资讯。 深度爆料,斗破苍穹年番70集剧情内容。萧炎对小医仙的信任可谓是深不可测,然而美杜莎与小医仙之间的隔阂却始终存在。尽管美杜莎和紫妍都已加入毒宗,但两人之间的冲突从未停…

模型剪枝Lab

这里是MIT 6.5940 Fall 2023的第一个实验Lab1的一些笔记,课程传送门:Han Lab Setup First, install the required packages and download the datasets and pretrained model. Here we use CIFAR10 dataset and VGG network which is the same as what…

java 之 泛型的详细介绍

文章目录 1. 为什么需要泛型?2. 泛型的基本概念3. 泛型类的例子4. 泛型方法的例子5. 泛型的好处 泛型使用的位置1. 泛型类(Generic Class):2. 泛型接口(Generic Interface):3. 泛型方法&#xf…

vue2按需导入Element(vite打包)

1.安装element 说明:-S是生产依赖。 npm install element-ui2 -S 2.安装babel-plugin-component 说明:-D是开发模式使用。 npm install babel-plugin-component -D 3. vite.config.js 说明:借助 babel-plugin-component ,我们可…

人工智能极简史:一文读懂ChatGPT的前世今生

2022年11月30日,OpenAI推出的一款人工智能技术驱动的自然语言处理工具——ChatGPT,迅速在社交媒体上走红,短短5天,注册用户数就超过100万。 2023年1月末,ChatGPT的月活用户已突破1亿,一度成为史上增长最快的…

JSON.parse --- 搜索框

一 &#xff0c; JSON.parse this.num_normsTwo JSON.parse(res.result.normsTwo) 二. 搜索框 <template><div class"app-container"><span style"margin-left:120px;margin-right: 20px;width: 100px; display: inline-block;">物…

大语言模型可以学习规则11.13

大型语言模型可以学习规则 摘要1 引言2 准备3 从假设到理论3.1 诱导阶段&#xff1a;规则生成和验证3.2 演绎阶段&#xff1a;使用规则库进行显式推理 4 实验评估实验装置4.2 数字推理 5 相关工作 摘要 当提示一些例子和中间步骤时&#xff0c;大型语言模型&#xff08;LLM&am…

【网络豆送书第六期】《嵌入式虚拟化技术与应用》

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆云计算学堂 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ 本期好书推荐&#xff1a;《嵌入式虚拟化技术与应用…

面试 | 再也不怕被问 Binder 机制了

Binder 机制 Binder 机制是 Android 特有的一种进程间通信&#xff08;IPC&#xff09;方式 1.1 Binder 机制的作用和原理&#xff1f; Linux系统将一个进程分为用户空间和内核空间。对于进程之间来说&#xff0c;用户空间的数据不可共享&#xff0c;内核空间的数据可共享&a…

Django下的Race Condition漏洞

目录 环境搭建 无锁无事务的竞争攻击复现 无锁有事务的竞争攻击复现 悲观锁进行防御 乐观锁进行防御 环境搭建 首先我们安装源码包&#xff1a;GitHub - phith0n/race-condition-playground: Playground for Race Condition attack 然后将源码包上传到Ubuntu 为了方便使…

python双端队列_中间是头两边是尾_两边是头中间是尾

双端队列的顺序表存储结构以及两种特殊的双端队列 双端队列 是一种允许我们同时从前端和后端添加和删除元素的特殊队列&#xff0c;它是队列和栈的结合体。 双端队列&#xff08;deque&#xff09;与队列&#xff08;queue&#xff09;就差了两个字&#xff0c;队列里元素只能…

uniapp——项目day04

购物车页面——商品列表区域 渲染购物车商品列表的标题区域 1. 定义如下的 UI 结构&#xff1a; 2.美化样式 渲染商品列表区域的基本结构 1. 通过 mapState 辅助函数&#xff0c;将 Store 中的 cart 数组映射到当前页面中使用&#xff1a; import badgeMix from /mixins/tab…

2023年【建筑电工(建筑特殊工种)】找解析及建筑电工(建筑特殊工种)复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 建筑电工(建筑特殊工种)找解析是安全生产模拟考试一点通生成的&#xff0c;建筑电工(建筑特殊工种)证模拟考试题库是根据建筑电工(建筑特殊工种)最新版教材汇编出建筑电工(建筑特殊工种)仿真模拟考试。2023年【建筑电…