OpenCV #以图搜图:均值哈希算法(Average Hash Algorithm)原理与实验

1. 介绍

均值哈希算法(Average Hash Algorithm) 是哈希算法的一种,主要用来做相似图片的搜索工作。

 

2. 原理

均值哈希算法(aHash)首先将原图像缩小成一个固定大小的像素图像,然后将图像转换为灰度图像,通过缩小图像的每个像素与平均灰度值的比较,生成一组哈希值。最后,利用两组图像的哈希值的汉明距离来评估图像的相似度。

魔法: 概括地讲,均值哈希算法一共可细分六步:

  1. 缩小图像: 将目标图像缩小为一个固定的大小,通常为8x8像素,总共64个像素。作用是去除各种图像尺寸和图像比例的差异,只保留结构、明暗等基本信息,目的是确保图像的一致性,降低计算的复杂度。
  2. 图像灰度化: 将缩小的图像转换为灰度图像。
  3. 灰度平均值: 计算灰度图像的平均灰度值。减少计算量。
  4. 比较平均值: 遍历灰度图像的每个像素,比较每个像素的灰度值是否大于或小于平均值。对于大于等于平均值的像素,将其表示为1,对于小于平均值的像素,将其表示为0。最后,得到一个64位的二进制值(8x8像素的图像)。
  5. 生成哈希值: 由于64位二进制值太长,所以按每4个字符为1组,由2进制转成16进制。这样就转为一个长度为16的字符串。这个字符串也就是这个图像可识别的哈希值,也叫图像指纹,即这个图像所包含的特征。
  6. 哈希值比较: 通过比较两个图像的哈希值的汉明距离(Hamming Distance),就可以评估图像的相似度,距离越小表示图像越相似。

 

3. 实验

第一步:缩小图像

将目标图像缩小为一个固定的大小,通常为8x8像素,总共64个像素。作用是去除各种图像尺寸和图像比例的差异,只保留结构、明暗等基本信息,目的是确保图像的一致性,降低计算的复杂度。

1)读取原图

# 测试图片路径
img_path = 'img_test/apple-01.jpg'# 通过OpenCV加载图像
img = cv2.imread(img_path)# 通道重排,从BGR转换为RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

aHash-0001

2)缩小原图

# 缩小图像:使用OpenCV的resize函数将图像缩放为8x8像素,采用Cubic插值方法进行图像重采样
img_resize = cv2.resize(img, (8, 8), cv2.INTER_CUBIC)

aHash-0002
OpenCV 的 cv2.resize() 函数提供了4种插值方法,以根据图像的尺寸变化来进行图像重采样。

  • cv2.INTER_NEAREST: 最近邻插值,也称为最近邻算法。它简单地使用最接近目标像素的原始像素的值。虽然计算速度快,但可能导致图像质量下降。
  • cv2.INTER_LINEAR: 双线性插值,通过对最近的4个像素进行线性加权来估计目标像素的值。比最近邻插值更精确,但计算成本略高。
  • cv2.INTER_CUBIC: 双三次插值,使用16个最近像素的加权平均值来估计目标像素的值。通常情况下,这是一个不错的插值方法,适用于图像缩小。
  • cv2.INTER_LANCZOS4: Lanczos插值,一种高质量的插值方法,使用Lanczos窗口函数。通常用于缩小图像,以保留图像中的细节和纹理。

第二步:图像灰度化

将缩小的图像转换为灰度图像。也就是说,所有像素点总共只有64种灰度颜色。

# 图像灰度化:将彩色图像转换为灰度图像。
img_gray = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)
print(f"缩放8x8的图像中每个像素的颜色=\n{img_gray}")

输出打印:

缩放8x8的图像中每个像素的颜色=
[[253 253 253 253 253 253 253 253][253 253 253 148 253 253 253 253][253 253 253 215 178 253 253 253][253 253 119  93 132 176 253 253][253 253  61  61  53 130 253 253][253 253 112  67  66 142 253 253][253 253 252  54  54 253 253 253][253 253 236  63 146 249 253 253]]

aHash-0003

第三步:灰度平均值

计算灰度图像的平均灰度值。减少计算量。

img_average = np.mean(img_gray) 
print(f"灰度图像中所有像素的平均值={img_average}")

输出打印:

灰度图像中所有像素的平均值=209.890625

第四步:比较平均值

遍历灰度图像的每个像素,比较每个像素的灰度值是否大于或小于平均值。对于大于等于平均值的像素,将其表示为1;对于小于平均值的像素,将其表示为0。最后,得到一组长64位的二进制字符串(8x8像素的图像)。因为对于机器而言,只认识0和1,所以这组64位的二进制就可以表示这张图像的结构和亮度分布。

# 遍历图像像素:嵌套循环遍历图像的所有像素,对比灰度图像的平均灰度值,转换为二进制的图像哈希值
img_hash_binary = [] 
for i in range(img_gray.shape[0]): for j in range(img_gray.shape[1]): if img_gray[i,j] >= img_average: img_hash_binary.append(1)else: img_hash_binary.append(0)
print(f"对比灰度图像的平均像素值降噪(图像的二进制哈希值)数组={img_hash_binary}")# 将列表中的元素转换为字符串并连接起来,形成一组64位的图像二进制哈希值字符串
img_hash_binary_str = ''.join(map(str, img_hash_binary))
print(f"对比灰度图像的平均像素值降噪(图像的二进制哈希值)={img_hash_binary_str}")

代码分解和含义如下:

  1. 初始化空列表:创建一个空的列表 img_hash_binary,用于存储图像的哈希值。
  2. 遍历图像像素:嵌套循环遍历图像的所有像素,其中 img_gray 是输入的灰度图像,img_gray.shape[0] 和 img_gray.shape[1] 分别表示图像的高度和宽度。
  3. 计算平均值:代码中使用变量 img_average 存储了一个平均值,用于与图像像素的灰度值进行比较。
  4. 根据亮度值生成哈希值:对于每个像素,代码比较像素的灰度值与平均值 (img_gray[i, j] >= img_average)。如果像素的灰度值大于或等于平均值,就将数字1添加到 img_hash_binary 列表中,表示该像素是亮的。如果像素的灰度值小于平均值,就将数字0添加到 img_hash_binary 列表中,表示该像素是暗的。
  5. 最终哈希值:完成循环后,img_hash_binary 列表将包含图像的二进制哈希值,其中每个元素代表一个像素的明暗情况。

输出打印:

对比灰度图像的平均像素值降噪(图像的二进制形式)数组=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1]
对比灰度图像的平均像素值降噪(图像的二进制形式)=1111111111101111111101111100001111000011110000111110011111100111       

或者,使用等价的 lambda 表达式。效果一样。

# lambda表达式
img_hash_binary_str = ""
for i in range(8):img_hash_binary_str += ''.join(map(lambda i: '0' if i < img_average else '1', img_gray[i]))
print(f"对比灰度图像的平均像素值降噪(图像的二进制哈希值)={img_hash_binary_str}")

输出打印:

对比灰度图像的平均像素值降噪(图像的二进制形式)=1111111111101111111101111100001111000011110000111110011111100111

第五步:生成哈希值

由于64位二进制值太长,所以按每4个字符为1组,由2进制转成16进制。这样就转为一个长度为16的字符串。这个字符串也就是这个图像可识别的哈希值,也叫图像指纹,即这个图像所包含的特征。

img_hash = ""
for i in range(0, 64, 4):img_hash += "".join('%x' % int(img_hash_binary_str[i : i + 4], 2))
print(f"图像可识别的哈希值={img_hash}")

代码分解和含义如下:

  1. 初始化为空字符串:创建一个空的字符串 img_hash,用于存储图像哈希值的十六进制表示。
  2. 遍历二进制哈希值:通过循环,代码以4位为一组遍历二进制哈希值 img_hash_binary_str。range(0, 64, 4) 确保代码在哈希值的每4位之间进行迭代。
  3. 将4位二进制转换为一个十六进制字符:在每次循环中,代码取出哈希值中的4位二进制(例如,img_hash_binary_str[i : i + 4]),然后使用’%x’ % int(…, 2) 将这4位二进制转换为一个十六进制字符。int(…, 2) 将二进制字符串转换为整数,‘%x’ 将整数转换为十六进制字符。
  4. 将十六进制字符追加到 img_hash:在每次循环中,得到的十六进制字符将被追加到 img_hash 字符串中。
  5. 最终哈希值:完成循环后,img_hash 将包含图像哈希值的十六进制表示,其中每个字符表示4位二进制。

输出打印:

图像可识别的哈希值=ffeff7c3c3c3e7e7

第六步:哈希值比较

通过比较两个图像的哈希值的汉明距离(Hamming Distance),就可以评估图像的相似度,距离越小表示图像越相似。

def hamming_distance(s1, s2):# 检查这两个字符串的长度是否相同。如果长度不同,它会引发 ValueError 异常,因为汉明距离只适用于等长的字符串if len(s1) != len(s2):raise ValueError("Input strings must have the same length")distance = 0for i in range(len(s1)):# 遍历两个字符串的每个字符,比较它们在相同位置上的值。如果发现不同的字符,将 distance 的值增加 1if s1[i] != s2[i]:distance += 1return distance

 

4. 测试

我们来简单测试一下基于均值哈希算法的以图搜图 – 基于一张原图找最相似图片,看看效果如何。
这里,我准备了10张图片,其中9张是苹果,但形态不一,1张是梨子。
aHash-0004
输出打印:

图片名称:img_test/apple-01.jpg,图片HASH:ffeff7c3c3c3e7e7,与图片1的近似值(汉明距离):0
图片名称:img_test/apple-02.jpg,图片HASH:ffcfc3e3e3e3e7ff,与图片1的近似值(汉明距离):8
图片名称:img_test/apple-03.jpg,图片HASH:ffe7c3c3c3c7c7ff,与图片1的近似值(汉明距离):7
图片名称:img_test/apple-04.jpg,图片HASH:e7e7c3c3c3eff7ff,与图片1的近似值(汉明距离):10
图片名称:img_test/apple-05.jpg,图片HASH:f3f3e7c7c3c7c7e7,与图片1的近似值(汉明距离):7
图片名称:img_test/apple-06.jpg,图片HASH:ffffd981818189dd,与图片1的近似值(汉明距离):13
图片名称:img_test/apple-07.jpg,图片HASH:fff7f3e3e3e3f0ff,与图片1的近似值(汉明距离):10
图片名称:img_test/apple-08.jpg,图片HASH:000006fdf171f9f8,与图片1的近似值(汉明距离):16
图片名称:img_test/apple-09.jpg,图片HASH:ffcfe7c1c1c3e7ff,与图片1的近似值(汉明距离):6
图片名称:img_test/pear-001.jpg,图片HASH:fffbe5c1c3c3c3ef,与图片1的近似值(汉明距离):8
耗时:0.09571695327758789

汉明距离:两个长度相同的字符串在相同位置上的字符不同的个数。
aHash-0005

简单的测试分析:

原图相似图片相似值(汉明距离)相似图片特点相似图片与原图Hash对比结果
图片01图片010自己自己与自己相似度100%
图片01图片096青苹果最相似。相同背景相同物体位置下最相似。
图片01图片03、图片057红蛇果(苹果)、青苹果(2D)次相似。同上,单物体对比时,背景、物体位置越近越相似。
图片01图片028两者几乎相似比较相似。影响相似距离的似乎是苹果下方的阴影有无。
图片01图片pear-0018黄色的梨子意外相似。相似搜索并不能识别物体/内容,因为工作原理是通过图片灰度后的灰色像素点位置与对比。
图片01图片0410原图像的180度旋转图相差甚远。对于原图旋转变换相对不敏感,因为均值哈希算法只捕获了图像的平均亮度和粗略结构。
图片01图片06、07、0810以上复杂、多主体、多色调较难分辨。复杂、多主体、多色调的图片较难与原图相似。

10张测试图片中,汉明距离在5以内1张;汉明距离在5以外9张。
从抽样简单测试结果看,平均哈希简单且计算速度快,但它对图像的细节变化比较敏感,容易受到局部图像的特性的干扰。

备注:如果汉明距离0,则表示这两张图片非常相似;如果汉明距离小于5,则表示有些不同,但比较相近;如果汉明距离大于10,则表明是完全不同的图片。

 

5. 总结

经过实验和测试,平均哈希算法优缺点明显。

特点: 传统
优点: 简单、计算效率高,适用于快速图像相似性比较。
缺点: 对于图片的旋转和主体内容变换相对不敏感;对于复杂、多主体、多色调的图片较难相似,因为它只捕获了图片的平均亮度和粗略结构。

 

6. 实验代码

"""
以图搜图:均值哈希算法(Average Hash Algorithm)的原理与实现
测试环境:win10 | python 3.9.13 | OpenCV 4.4.0 | numpy 1.21.1
实验时间:2023-10-20
"""import cv2
import time
import numpy as np
import matplotlib.pyplot as pltdef get_hash(img_path):# 读取图像:通过OpenCV的imread加载图像# 缩小图像:使用OpenCV的resize函数将图像缩放为8x8像素,采用Cubic插值方法进行图像重采样img_rgb = cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB)# 使用OpenCV的resize函数将图像缩放为8x8像素,采用Cubic插值方法进行图像重采样img_resize = cv2.resize(img_rgb, (8, 8), cv2.INTER_CUBIC)# 图像灰度化:将彩色图像转换为灰度图像。较少计算量。img_gray = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)# print(f"缩放8x8的图像中每个像素的颜色=\n{img_gray}")# 灰度平均值:计算灰度图像的平均灰度值img_average = np.mean(img_gray) # print(f"灰度图像中所有像素的平均值={img_average}")"""# # 比较平均值:嵌套循环遍历图像的所有像素,对比灰度图像的平均灰度值,转换为二进制的图像哈希值# # img_gray:是灰度图像# # img_gray.shape[0] 和 img_gray.shape[1] 分别表示图像的高度和宽度# img_hash_binary = [] # for i in range(img_gray.shape[0]): #     for j in range(img_gray.shape[1]): #         if img_gray[i,j] >= img_average: #             img_hash_binary.append(1)#         else: #             img_hash_binary.append(0)# print(f"对比灰度图像的平均像素值降噪(图像的二进制哈希值)数组={img_hash_binary}")# # 将列表中的元素转换为字符串并连接起来,形成一组64位的图像二进制哈希值字符串# img_hash_binary_str = ''.join(map(str, img_hash_binary))# print(f"对比灰度图像的平均像素值降噪(图像的二进制哈希值)={img_hash_binary_str}")# # 生成哈希值# img_hash = ""# # 遍历二进制哈希值:通过循环,代码以4位为一组遍历二进制哈希值 img_hash_binary_str。# # range(0, 64, 4) 确保代码在哈希值的每4位之间进行迭代。# for i in range(0, 64, 4):#     # 将4位二进制转换为一个十六进制字符#     # 在每次循环中,代码取出哈希值中的4位二进制(例如,img_hash_binary_str[i : i + 4])#     # 然后使用'%x' % int(..., 2)将这4位二进制转换为一个十六进制字符。#     # int(..., 2)将二进制字符串转换为整数,'%x'将整数转换为十六进制字符。#     # 将十六进制字符追加到 img_hash:在每次循环中,得到的十六进制字符将被追加到 img_hash 字符串中。#     img_hash += "".join('%x' % int(img_hash_binary_str[i : i + 4], 2))# print(f"图像可识别的哈希值={img_hash}")"""# 图像二进制哈希值img_hash_binary_str = ''for i in range(8):img_hash_binary_str += ''.join(map(lambda i: '0' if i < img_average else '1', img_gray[i]))# print(f"对比灰度图像的平均像素值降噪(图像的二进制哈希值)={img_hash_binary_str}")# 图像可识别哈希值img_hash = ''.join(map(lambda x:'%x' % int(img_hash_binary_str[x : x + 4], 2), range(0, 64, 4)))# print(f"图像可识别的哈希值={img_hash}")return img_hash# 汉明距离:计算两个等长字符串(通常是二进制字符串或位字符串)之间的汉明距离。用于确定两个等长字符串在相同位置上不同字符的数量。
def hamming_distance(s1, s2):# 检查这两个字符串的长度是否相同。如果长度不同,它会引发 ValueError 异常,因为汉明距离只适用于等长的字符串if len(s1) != len(s2):raise ValueError("Input strings must have the same length")distance = 0for i in range(len(s1)):# 遍历两个字符串的每个字符,比较它们在相同位置上的值。如果发现不同的字符,将 distance 的值增加 1if s1[i] != s2[i]:distance += 1return distance# --------------------------------------------------------- 测试 ---------------------------------------------------------time_start = time.time()img_1 = 'img_test/apple-01.jpg'
img_2 = 'img_test/apple-02.jpg'
img_3 = 'img_test/apple-03.jpg'
img_4 = 'img_test/apple-04.jpg'
img_5 = 'img_test/apple-05.jpg'
img_6 = 'img_test/apple-06.jpg'
img_7 = 'img_test/apple-07.jpg'
img_8 = 'img_test/apple-08.jpg'
img_9 = 'img_test/apple-09.jpg'
img_10 = 'img_test/pear-001.jpg'img_hash1 = get_hash(img_1)
img_hash2 = get_hash(img_2)
img_hash3 = get_hash(img_3)
img_hash4 = get_hash(img_4)
img_hash5 = get_hash(img_5)
img_hash6 = get_hash(img_6)
img_hash7 = get_hash(img_7)
img_hash8 = get_hash(img_8)
img_hash9 = get_hash(img_9)
img_hash10 = get_hash(img_10)distance1 = hamming_distance(img_hash1, img_hash1)
distance2 = hamming_distance(img_hash1, img_hash2)
distance3 = hamming_distance(img_hash1, img_hash3)
distance4 = hamming_distance(img_hash1, img_hash4)
distance5 = hamming_distance(img_hash1, img_hash5)
distance6 = hamming_distance(img_hash1, img_hash6)
distance7 = hamming_distance(img_hash1, img_hash7)
distance8 = hamming_distance(img_hash1, img_hash8)
distance9 = hamming_distance(img_hash1, img_hash9)
distance10 = hamming_distance(img_hash1, img_hash10)time_end = time.time()print(f"图片名称:{img_1},图片HASH:{img_hash1},与图片1的近似值(汉明距离):{distance1}")
print(f"图片名称:{img_2},图片HASH:{img_hash2},与图片1的近似值(汉明距离):{distance2}")
print(f"图片名称:{img_3},图片HASH:{img_hash3},与图片1的近似值(汉明距离):{distance3}")
print(f"图片名称:{img_4},图片HASH:{img_hash4},与图片1的近似值(汉明距离):{distance4}")
print(f"图片名称:{img_5},图片HASH:{img_hash5},与图片1的近似值(汉明距离):{distance5}")
print(f"图片名称:{img_6},图片HASH:{img_hash6},与图片1的近似值(汉明距离):{distance6}")
print(f"图片名称:{img_7},图片HASH:{img_hash7},与图片1的近似值(汉明距离):{distance7}")
print(f"图片名称:{img_8},图片HASH:{img_hash8},与图片1的近似值(汉明距离):{distance8}")
print(f"图片名称:{img_9},图片HASH:{img_hash9},与图片1的近似值(汉明距离):{distance9}")
print(f"图片名称:{img_10},图片HASH:{img_hash10},与图片1的近似值(汉明距离):{distance10}")print(f"耗时:{time_end - time_start}")

 

7. 疑难杂症

问题1: 为什么通过 cv2.imread(img_path) 加载的图像,显示出来之后,原图由红色变成了蓝色?
aHash-0006
问题原因: 如果原图是红色的,但通过OpenCV加载显示的图像是蓝色的,这可能是由于图像的通道顺序不同导致的。在OpenCV中,图像的通道顺序通常是BGR(蓝绿红),而在一些其他库(如matplotlib)中,通常使用RGB(红绿蓝)通道顺序。
解决方案: 使用OpenCV的通道重排功能,将图像的通道顺序从BGR转换为RGB,然后再显示图像。以下是修改后的代码:

# 通过OpenCV加载图像
img = cv2.imread(img_path)# 通道重排,从BGR转换为RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

问题2: 为什么使用了 cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ,但显示出来图像是彩色的?
aHash-0007
问题原因: 这可能是由于你使用了 matplotlib 来显示图像,而 matplotlib 默认将灰度图像显示为伪彩色图像。Matplotlib会将单通道的灰度图像(每个像素只有一个亮度值)显示为伪彩色图像以便于可视化。
解决方案: 在使用 imshow 函数显示图像时,添加 cmap 参数,并将其设置为 ‘gray’,以确保图像以灰度形式显示。例如:

# 测试图片路径
img_path = 'img_test/apple-01.jpg'# 通过OpenCV加载图像
img = cv2.imread(img_path)# 通道重排,从BGR转换为RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 使用OpenCV的resize函数将图像缩放为8x8像素,采用Cubic插值方法
img_resize = cv2.resize(img_rgb, (8, 8), cv2.INTER_CUBIC)# 灰度化:将彩色图像转换为灰度图像。
img_gray = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)# 灰度形式查看图像
plt.imshow(img_gray, cmap='gray')
# 显示图像
plt.show()

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

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

相关文章

多级缓存入门

文章目录 什么是多级缓存JVM进程缓存环境准备安装MySQL导入Demo工程导入商品查询页面 初识Caffeine Lua语法初识Lua第一个lua程序变量和循环Lua的数据类型声明变量循环 条件控制、函数函数条件控制 多级缓存安装OpenRestyOpenResty快速入门反向代理流程OpenResty监听请求编写it…

k8s kubeadm配置

master 192.168.41.30 docker、kubeadm、kubelet、kubectl、flannel node01 192.168.41.31 docker、kubeadm、kubelet、kubectl、flannel node02 192.168.41.32 do…

一文精通C++ -- 继承

前言&#xff1a;继承是C类和对象三大特性中关键的一环&#xff0c;上承封装&#xff0c;下接多态&#xff0c;C中的继承是一种面向对象编程的概念&#xff0c;它允许一个类&#xff08;称为子类或派生类&#xff09;继承另一个类&#xff08;称为父类或基类&#xff09;的属性…

【Java网络编程】 三

本文主要介绍了TCP版本的回显服务器的编写。 一.TCP版本回显服务器 1.服务器 服务器的实现流程 1.接收请求并解析 2.根据请求计算出响应&#xff08;业务流程&#xff09; 3.把响应返回给客户端 代码&#xff1a; import java.io.IOException; import java.io.InputStream; i…

酷开科技 | 酷开系统沉浸式大屏游戏更解压!

随着家庭娱乐需求日益旺盛&#xff0c;越来越多的家庭消费者和游戏玩家开始追求大屏游戏带来的沉浸感。玩家在玩游戏的时候用大屏能获得更广阔的视野和更出色的视觉包围感&#xff0c;因此用大屏玩游戏已经成为了一种潮流。用酷开系统玩大屏游戏&#xff0c;过瘾又刺激&#xf…

对比Vue2和Vue3的自定义指令

一、自定义指令简介 自定义指令是Vue提供的能力,用于注册自定义的指令,从而实现一些自定义的DOM操作。 二、Vue2中自定义指令 在Vue2中,自定义指令通过全局方法Vue.directive()进行注册: // 注册全局指令v-focus Vue.directive(focus, {inserted: function(el) {el.focus()…

ubuntu 安装 gnome 安装 xrdp

先安装xrdp 更新 apt-get sudo apt-get update && apt-get upgrade安装图形包 apt-get install xubuntu-desktop安装 xrdp apt-get install xrdp安装 xfce4 apt-get install xfce4配置 xfce4 Add xfce to the xfce desktop window manager autorun by fixing the …

rstudio server 服务器卡死了怎么办

欢迎关注weixin:生信小博士 #rstudio 卡死了怎么办 cd ~/.local/share/ ls rm -fr rstudio.old mv ~/.rstudio ~/.rstudio.oldcd ~/.config/ rm -fr .rstudio.old mv ~/.config/rstudio/ ~/.config/rstudio.oldps -ef|grep t040413 |grep rsession |awk {print $2}| xarg…

LabVIEW基于机器视觉的钢轨表面缺陷检测系统

LabVIEW基于机器视觉的钢轨表面缺陷检测系统 机器视觉检测技术和LabVIEW软件程序&#xff0c;可以实现轨道工件的表面质量。CMOS彩色工业相机采集的图像通过图像预处理、图像阈值分割、形态分析、特征定位和图案匹配进行处理和分析。图形显示界面采用LabVIEW软件编程设计&…

postgresql|数据库|序列Sequence的创建和管理

前言&#xff1a; Sequence也是postgresql数据库里的一种对象&#xff0c;其属性如同索引一样&#xff0c;但通常Sequence是配合主键来工作的&#xff0c;这一点不同于MySQL&#xff0c;MySQL的主键自增仅仅是主键的属性做一个更改&#xff0c;而postgresql的主键自增是需要序…

上云容灾如何实现碳中和-万博智云受邀参加1024程序员节数据技术论坛并发表演讲

近日&#xff0c;2023长沙中国1024程序员节在长沙召开。 长沙中国1024程序员节继2020年后已成功连续举办三届&#xff0c;逐步成为 IT 行业引领技术前沿、推动应用创新发展的高影响力年度盛会。是 IT 领域新技术、新产品、新服务的重要发布平台。 万博智云CEO Michael受邀参加…

深度学习_4_实战_直线最优解

梯度 实战 代码&#xff1a; # %matplotlib inline import random import torch import matplotlib.pyplot as plt # from d21 import torch as d21def synthetic_data(w, b, num_examples):"""生成 Y XW b 噪声。"""X torch.normal(0,…

手把手教你玩转单目摄像头(OpenCv+Python)

目录 ​编辑 一&#xff0c;单目应用前景 二&#xff0c;打开摄像头 三&#xff0c;设置分辨率 四&#xff0c;摄像头拍照 五&#xff0c;录制视频 六&#xff0c;单目结合OpenCV的实际应用 一&#xff0c;单目应用前景 单目视觉&#xff08;monocular vision&#xff0…

Android MQTT连接阿里云使用Json解析数据

Android Studio 连接阿里云订阅主题然后使用JSON解析数据非常好用 导入MQTT的JAR包1、在项目中添加依赖然后使用Studio 去下载库2、直接下载JAR包&#xff0c;然后作为库进行导入 环境验证&#xff1a;给程序进行联网权限XML布局文件效果如下&#xff1a; MainActitive.java 主…

JavaScript进阶 第四天笔记——深浅拷贝、this绑定、防抖节流

JavaScript 进阶 - 第4天 深浅拷贝 浅拷贝 首先浅拷贝和深拷贝只针对引用类型 浅拷贝&#xff1a;拷贝的是地址 常见方法&#xff1a; 拷贝对象&#xff1a;Object.assgin() / 展开运算符 {…obj} 拷贝对象拷贝数组&#xff1a;Array.prototype.concat() 或者 […arr] 如…

k8s-----18、Ingress(对外服务)

Ingress 1、Ingress概念2、 pod和ingress的关系3、 Ingress的工作流程4、 使用步骤5、对外暴露应用实战5.1 创建nginx应用&#xff0c;对外暴露端口使用NodePort5.2 部署ingress controller5.3 创建ingress规则5.4 访问 1、Ingress概念 k8s 对外暴露服务&#xff08;service&am…

day50 --动态规划9

198.打家劫舍 213.打家劫舍II 337.打家劫舍III 第一题&#xff1a;打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一…

堆(二叉树,带图详解)

一.堆 1.堆的概念 2.堆的存储方式 逻辑结构 物理结构 2.堆的插入问题 3.堆的基本实现&#xff08;代码&#xff09;&#xff08;以小堆为例&#xff09; 1.堆的初始化 2. 向上调整 3.插入结点 4. 交换函数、堆的打印 5.向下调整 6.删除根节点并调整成小根堆 7.获取堆…

3D模型格式转换工具HOOPS Exchange助力SIMCON搭建注塑项目

行业&#xff1a;设计与制造 / 注塑成型 / 模拟 挑战&#xff1a;注塑成型商面临着以高效的方式为客户生产零件的挑战。需要大量的试验才能生产出适合的零件&#xff0c;同时模具需要进行多次物理修改&#xff0c;每次修改周期最长需要四个星期&#xff0c;成本高达四到五位数…

第1章 Java、IDEA环境部署与配置

JavaEE简介与IDE环境部署 课程目录 JavaEE简介JDK环境部署IntelliJ IDEA环境部署 JavaEE简介 1. JavaEE是什么&#xff1f; Java EE&#xff08;Java Platform&#xff0c;Enterprise Edition&#xff09;是sun公司&#xff08;2009年4月20日甲骨文将其收购&#xff09;推…