当前位置: 首页 > news >正文

用封面预测书的价格【图像回归】

今天,我将介绍计算机视觉的深度学习应用,用封面简单地估算一本书的价格。 我没有看到很多关于图像回归的文章,所以我为你们写这篇文章。

距离我上一篇文章已经过去很长时间了,我不得不承认,作为一名数据科学家,我用于副业或写文章的时间更少了(或者,也许这只是我的懒惰)。

如果你对本文旁边的编码感兴趣,请查看此 GitHub。

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 

1、数据

本文使用的数据可以从此处提供的 Kaggle 数据集下载。 它包含来自 BookDepository 网站的书籍特征数据,但我们将主要使用书籍封面图像来训练深度学习模型。 现在让我们看看图书数据是什么样的。

import pandas as pd 
df= pd.read_csv('main_dataset.csv')
df

数据的形状为  (32581, 11),但在本文中,我们将仅关注“图像”和“价格”字段给出的书籍封面图像数据和价格标签(不是旧价格)。 如果仔细查看加载的数据,我们会发现除了“图像”列中给出的图像 URL 之外,我们没有图像数据。 原因是图像数据是非结构化数据,不能与其他数据采用相同的格式。

抛开这些原因不谈,我如何访问这种格式的图像数据? 我需要创建一个函数来从这些 URL 中获取图像并将它们全部加载到文件夹图像中。

2、加载并查看图片

from matplotlib import pyplot as plt
import numpy as np
import urllib
import cv2
def show_image_from_url(image_url):
"""Fetches image online from the image_url and plots it as it is using matplotlib's pyplot's image show"""
response = urllib.request.urlopen(image_url)image = np.asarray(bytearray(response.read()), dtype="uint8")image_bgr = cv2.imdecode(image, cv2.IMREAD_COLOR)image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)plt.imshow(image_rgb), plt.axis('off')

上面的函数将从图像 URL 获取图像,并使用 matplotlib 和 OpenCV 库显示图像。 让我们看看该函数是如何工作的:

plt.figure()
show_image_from_url(df['image'].loc[10])

我们得到了Michael Mosley 撰写的 The Clever Guts Diet 一书的封面。 现在你看到我们可以显示给定 URL 中的图像,是时候获取图像并将其加载到你的计算机以将其放入深度学习中了。

3、图像预处理

下面是一个相当长的函数,因为它不仅加载图像,还进行图像预处理—转换为灰度、裁剪和调整图像大小。 所有这些预处理都是为了让覆盖数据更加一致,适合即将到来的深度学习:

def image_processing(image_url):
"""Converts the URL of any image to an array of size 100x1 The array represents an OpenCV grayscale version of the original imageThe image will get cropped along the biggest red contour (4 line polygon) tagged on the original image (if any)"""
#Download from image url and import it as a numpy arrayresponse = urllib.request.urlopen(image_url)image = np.asarray(bytearray(response.read()), dtype="uint8")
#Read the numpy arrays as color images in OpenCVimage_bgr = cv2.imdecode(image, cv2.IMREAD_COLOR)
#Convert to HSV for creating a maskimage_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
#Convert to grayscale that will actually be used for training, instead of color image image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
#Create a mask that detects the red rectangular tags present in each imagemask = cv2.inRange(image_hsv, (0,255,255), (0,255,255))
#Get the coordinates of the red rectangle in the image, #But take entire image if mask fails to detect the red rectangleif len(np.where(mask != 0)[0]) != 0:y1 = min(np.where(mask != 0)[0])y2 = max(np.where(mask != 0)[0])else:y1 = 0                                     y2 = len(mask)
if len(np.where(mask != 0)[1]) != 0:x1 = min(np.where(mask != 0)[1])x2 = max(np.where(mask != 0)[1])else:x1 = 0x2 = len(mask[0])
#Crop the grayscle image along those coordinatesimage_cropped = image_gray[y1:y2, x1:x2]if image_cropped.size ==0:print(image_url)return image_croppedelse:#Resize the image to 100x100 pixels sizeimage_100x100 = cv2.resize(image_cropped, (100, 100))
#Save image as in form of array of 10000x1image_arr = image_100x100.flatten()
return image_arr

预处理的阶段包括:

  • 灰度化:灰度表示经常用于提取描述符而不是直接对彩色图像进行操作的主要原因是灰度简化了算法并降低了计算要求。 大多数时候,HSV 格式中的颜色并不重要,灰度可以轻松完成相同的工作。
  • 裁剪:图像裁剪是一种常见的照片处理过程,它通过删除不需要的区域来改善整体构图。 显然,图像的角落并不是人类感知图像的焦点,我们只关注中心。 书的封面一角并没有对其书的价格留下任何解释力,而且大部分都是相同的。
  • 调整大小:为了促进小批量学习,我们需要给定批次内的图像具有固定的形状。 这就是为什么需要初始调整大小的原因。 我们首先将所有图像的大小调整为 (300 x 300) 形状,然后学习它们在 (150 x 150) 分辨率下的最佳表示。 调整大小并不能以任何方式帮助我们改进模型,这只是数据通过神经网络的方式,需要相同的结构。

4、加载数据

现在我们将该函数应用于图像 URL 列以获取图像数据。 请注意,这将花费你一两个小时来加载整个数据集。 如果想快速工作,你可以加载至少 2000 个 URL,这将花费大约 20 到 30 分钟。

from tqdm import tqdm
for url in tqdm(df['image'].tolist()[:]): # 3000 urls is enoughimage_list.append(image_processing(url))

请注意,你的图像不再是 PNG 或 JPEG。 现在它是 NumPy 对象中具有灰度的像素向量。 这就是你需要在深度学习模型中传递的内容。

X = np.array(image_list)
np.save('processed_100x100_image.npy',X/255,allow_pickle=True)
book_array = np.load('processed_100x100_image.npy',allow_pickle=True)

现在,加载数据并将其保存在 image_list 中,它只是存储在你的代码中,这是不好的做法,因为每次想要再次获取这些数据时,都必须浪费 30 分钟。 所以这里需要将那些处理后的图像数据保存到本地计算机中。

5、清理不同尺寸的图像和价格标签

要将数据传递到深度学习模型中,所有数据都需要具有相同的维度,即 100x100。 但是,当我查看处理后的图像 NumPy 数组时,我发现存在一些错误,即某些图像与其他图像的尺寸不同,因此我们需要在训练模型之前删除这些图像。

#remove non 10000 dimension out of the numpy array
X =[]
exclude =[]
for i in range(len(book_array)):if book_array[i].shape == (10000,):X.append(book_array[i])else:exclude.append(i)
X =np.array(X)
#also remove from the dataframe
df.drop(df.index[exclude],inplace=True)

在这里,我删除了与 100x100 尺寸不同的数据,并从数据框中删除了这些数据,因为我们需要使用价格标签数据,而我们不希望有任何复杂的数据映射或不匹配。

import re
df['price'] = df.price.apply(lambda x :re.sub("[^0-9.]",'',x)).apply(float)

价格标签中会有非数字值,如“$”、“dollars”等,不适用于运行深度模型。 我将使用正则表达式仅保留数字。

6、预处理后的图像示例

执行如下代码随机选择两张预处理后的图片并显示:

np.random.seed(17)
for i in np.random.randint(0, len(book_array), 2):plt.figure()plt.imshow(book_array[i].reshape(100, 100), cmap='gray'), plt.axis('off')

 

7、卷积神经网络

为了估算这本书的价格,在这项任务中,我将使用卷积神经网络或 CNN,它是针对涉及图像数据作为输入的任何类型的预测问题最有效的深度学习模型之一。

简而言之,CNN 算法会将图像简化为更易于处理的形式,而不会丢失对于获得良好预测至关重要的特征。

from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, BatchNormalization
from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense
from tensorflow.keras.losses import categorical_crossentropy
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.models import load_model
#Define a Convolutional Neural Network Model
model = Sequential()
model.add(Conv2D(filters = 16, kernel_size = (3, 3), activation='relu',input_shape = input_shape))
model.add(BatchNormalization())
model.add(Conv2D(filters = 16, kernel_size = (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPool2D(strides=(2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters = 32, kernel_size = (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(filters = 32, kernel_size = (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPool2D(strides=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.4))
#model.add(Dense(n_classes, activation='softmax'))
model.add(Dense(1, activation='relu'))
learning_rate = 0.001
model.compile(loss = 'mse',optimizer = Adam(learning_rate))
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 98, 98, 16)        160       
_________________________________________________________________
batch_normalization_4 (Batch (None, 98, 98, 16)        64        
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 96, 96, 16)        2320      
_________________________________________________________________
batch_normalization_5 (Batch (None, 96, 96, 16)        64        
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 48, 48, 16)        0         
_________________________________________________________________
dropout_4 (Dropout)          (None, 48, 48, 16)        0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 46, 46, 32)        4640      
_________________________________________________________________
batch_normalization_6 (Batch (None, 46, 46, 32)        128       
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 44, 44, 32)        9248      
_________________________________________________________________
batch_normalization_7 (Batch (None, 44, 44, 32)        128       
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 22, 22, 32)        0         
_________________________________________________________________
dropout_5 (Dropout)          (None, 22, 22, 32)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 15488)             0         
_________________________________________________________________
dense_3 (Dense)              (None, 512)               7930368   
_________________________________________________________________
dropout_6 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_4 (Dense)              (None, 1024)              525312    
_________________________________________________________________
dropout_7 (Dropout)          (None, 1024)              0         
_________________________________________________________________
dense_5 (Dense)              (None, 1)                 1025      
=================================================================
Total params: 8,473,457
Trainable params: 8,473,265
Non-trainable params: 192

我们将创建一个具有四个卷积层和过滤器 [16,16,32,32] 的 CNN 模型,然后该架构师将池化特征图转换为单个列,并传递到全连接层。

save_at = "model_regression.hdf5"
save_best2 = ModelCheckpoint (save_at, monitor='val_accuracy', verbose=0, save_best_only=True, save_weights_only=False, mode='max')
#set up the x, y for training 
Y = np.array(df.price.tolist())
X_test = X[30000:,]
Y_test = Y[30000:,]
X_train, X_val, Y_train, Y_val = train_test_split(X[:30000,], Y[:30000,], test_size=0.15, random_state=13)
img_rows, img_cols = 100, 100
input_shape = (img_rows, img_cols, 1)
X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
X_val = X_val.reshape(X_val.shape[0], img_rows, img_cols, 1)

前三行是设置训练完成后保存模型的参数。 剩下的就是为训练集和测试集设置目标或价格为 y。 现在我们正在使用 15 个 epoch 和 batch_size 为 100 来训练模型。如果你的计算机有足够的资源,请继续输入与 batch_size 一样多的数据,然后运行以下代码:

history = model.fit( X_train, Y_train, epochs = 15, batch_size = 100, callbacks=[save_best2], verbose=1, validation_data = (X_val, Y_price_val))

在这里,你可以看到模型正在过度拟合,绿线或验证损失约为 200,而红线或训练损失则越来越低。 当我将模型设置为保存最低的验证损失时,我们的模型性能将在第七个epoch保存。

plt.figure(figsize=(6, 5))
# training loss
plt.plot(history.history['loss'], color='r')
#validation loss
plt.plot(history.history['val_loss'], color='g')
plt.show()

让我们看看模型结果是什么:

Y_pred = np.round(model.predict(X_test))
np.random.seed(23)
for rand_num in np.random.randint(0, len(Y_test), 10):plt.figure()plt.imshow(X_test[rand_num].reshape(100, 100),cmap='gray'), plt.axis('off')if np.where(Y_pred[rand_num] < 10)[0].sum() == np.where(Y_test[rand_num] <10)[0].sum():plt.title(str(Y_pred[rand_num]) +' dollars', color='g')else :plt.title(str(Y_pred[rand_num]) +' dollars', color='r')

 

8、进一步的工作

我我们构建了一个基于封面的书籍价格预测器,希望你也可以将其应用于其他应用程序。 请注意,该模型仍然需要针对过度拟合进行调整,以使其能够很好地适应现实世界。 你可以采取一下错误来解决 CNN 中的过度拟合问题。

  • 添加更多数据
  • 使用数据增强
  • 使用泛化良好的架构
  • 添加正则化(主要是dropout,L1/L2正则化也是可以的)
  • 降低架构复杂性。

原文链接:用封面预测书价 - BimAnt

相关文章:

用封面预测书的价格【图像回归】

今天&#xff0c;我将介绍计算机视觉的深度学习应用&#xff0c;用封面简单地估算一本书的价格。 我没有看到很多关于图像回归的文章&#xff0c;所以我为你们写这篇文章。 距离我上一篇文章已经过去很长时间了&#xff0c;我不得不承认&#xff0c;作为一名数据科学家&#x…...

阿里云服务器e实例40G ESSD Entry系统盘、2核2G3M带宽99元

阿里云99元服务器新老用户同享2核2G经济型e实例、3M固定带宽和40G ESSD Entry系统盘&#xff0c;老用户也可以买&#xff0c;续费不涨价依旧是99元一年&#xff0c;阿里云百科aliyunbaike.com分享阿里云3M带宽服务器40G ESSD Entry云盘性能说明&#xff1a; 阿里云99元服务器配…...

Datawhale智能汽车AI挑战赛

1.赛题解析 赛题地址&#xff1a;https://tianchi.aliyun.com/competition/entrance/532155 任务&#xff1a; 输入&#xff1a;元宇宙仿真平台生成的前视摄像头虚拟视频数据&#xff08;8-10秒左右&#xff09;&#xff1b;输出&#xff1a;对视频中的信息进行综合理解&…...

pyclipper和ClipperLib操作多边型

目录 1. 等距离缩放多边形 1.1 python 1.2 c 1. 等距离缩放多边形 1.1 python 环境配置pip install opencv-python opencv-contrib-python pip install pyclipper pip install numpy import cv2 import numpy as np import pyclipperdef equidistant_zoom_contour(contour…...

Golang 协程、主线程

Go协程、Go主线程 1)Go主线程(有程序员直接称为线程/也可以理解成进程):一个Go线程上&#xff0c;可以起多个协程&#xff0c;你可以这样理解&#xff0c;协程是轻量级的线程。 2)Go协程的特点 有独立的栈空间 共享程序堆空间 调度由用户控制 协程是轻量级的线程 go线程-…...

【SA8295P 源码分析】125 - MAX96712 解串器 start_stream、stop_stream 寄存器配置 过程详细解析

【SA8295P 源码分析】125 - MAX96712 解串器 start_stream、stop_stream 寄存器配置 过程详细解析 一、sensor_detect_device():MAX96712 检测解串器芯片是否存在,获取chip_id、device_revision二、sensor_detect_device_channels() :MAX96712 解串器 寄存器初始化 及 detec…...

pandas教程:Apply:General split-apply-combine 通常的分割-应用-合并

文章目录 10.3 Apply&#xff1a;General split-apply-combine&#xff08;应用&#xff1a;通用的分割-应用-合并&#xff09;1 Suppressing the Group Keys&#xff08;抑制组键&#xff09;2 Quantile and Bucket Analysis&#xff08;分位数与桶分析&#xff09;3 Example:…...

第一讲之递归与递推下篇

第一讲之递归与递推下篇 带分数费解的开关飞行员兄弟翻硬币 带分数 用暴力将所有全排列的情况都算出来 > 有三个数&#xff0c;a,b,c 每种排列情况&#xff0c;可以用两层for循环&#xff0c;暴力分为三个部分&#xff0c;每个部分一个数 当然注意这里&#xff0c;第一层fo…...

第十六篇-Awesome ChatGPT Prompts-备份

Awesome ChatGPT Prompts——一个致力于提供挖掘ChatGPT能力的Prompt收集网站 https://prompts.chat/ 2023-11-16内容如下 ✂️Act as a Linux Terminal Contributed by: f Reference: https://www.engraved.blog/building-a-virtual-machine-inside/ I want you to act as a…...

Python Web框架Django

Python Web框架Django Django简介第一个Django应用Django核心概念Django django-adminDjango项目结构Django配置文件settingsDjango创建和配置应用Django数据库配置Django后台管理Django模型Django模型字段Django模型关联关系Django模型Meta 选项Django模型属性ManagerDjango模…...

1.Spring的简单使用

简介 本文是介绍spring源码的开始&#xff0c;先了解最基础的使用&#xff0c;最深入源码。 spring源码下载地址 https://github.com/spring-projects/spring-framework.git 依赖 依赖 spring-context dependencies {implementation(project(":spring-context")…...

02.智慧商城——vant组件库使用和vw适配

01. vant组件库及Vue周边的其他组件库 组件库&#xff1a;第三方封装好了很多很多的组件&#xff0c;整合到一起就是一个组件库。 https://vant-contrib.gitee.io/vant/v2/#/zh-CN/ 比如日历组件、键盘组件、打分组件、下拉筛选组件等 组件库并不是唯一的&#xff0c;常用的组…...

Android笔记(十三):结合JetPack Compose和CameraX实现视频的录制和存储

在“Android笔记&#xff08;八&#xff09;&#xff1a;基于CameraX库结合Compose和传统视图组件PreviewView实现照相机画面预览和照相功能”&#xff0c;文中介绍了拍照功能的实现&#xff0c;在本文中将介绍结合JetPack Compose和CameraX实现视频的录制。 新建一个项目 在项…...

【开题报告】基于SpringBoot的音乐鉴赏平台的设计与实现

1.研究背景与意义 音乐是人类文化的重要组成部分&#xff0c;具有广泛的影响力和吸引力。然而&#xff0c;随着数字化时代的到来&#xff0c;传统的音乐鉴赏方式面临一些挑战。因此&#xff0c;设计和开发一个基于Spring Boot的音乐鉴赏平台&#xff0c;能够满足用户对音乐欣赏…...

云原生 黑马Kubernetes教程(K8S教程)笔记——第一章 kubernetes介绍——Master集群控制节点、Node工作负载节点、Pod控制单元

参考文章&#xff1a;kubernetes介绍 文章目录 第一章 kubernetes介绍1.1 应用部署方式演变传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上虚拟化部署&#xff1a;可以在一台物理机上运行多个虚拟机&#xff0c;每个虚拟机都是独立的一个环境&…...

ElasticSearch 安装(单机版本)

文章目录 ElasticSearch 安装&#xff08;单机版本&#xff09;环境配置下载安装包调整系统参数安装启动并验证 ElasticSearch 安装&#xff08;单机版本&#xff09; 此文档演示 ElasticSearch 的单机版本在 CentOS 7 环境下的安装方式以及相关的配置。 环境配置 Linux 主机一…...

读书笔记:《BackTrader 量化交易案例图解》

BackTrader 量化软件&#xff1a;https://github.com/mementum/backtrader -> bt 量化框架&#xff08;前身&#xff09;&#xff1a;https://github.com/pmorissette/bt-> ffn 量化框架&#xff08;前前身&#xff09;&#xff1a;https://github.com/pmorissette/ffn T…...

CentOS 7 免密密钥登陆sftp服务 —— 筑梦之路

为什么用sftp而不是ftp&#xff1f; sftp是使用ssh协议安全加密的文件传输协议&#xff0c;ftp在很多时候都是使用的明文传输&#xff0c;相对来说容易被抓包&#xff0c;存在安全隐患。 需求说明 1. 使用sftp代替ftp来做文件存储&#xff0c;锁定目录&#xff0c;不允许用户切…...

记一次 .NET 某券商论坛系统 卡死分析

一&#xff1a;背景 1. 讲故事 前几个月有位朋友找到我&#xff0c;说他们的的web程序没有响应了&#xff0c;而且监控发现线程数特别高&#xff0c;内存也特别大&#xff0c;让我帮忙看一下怎么回事&#xff0c;现在回过头来几经波折&#xff0c;回味价值太浓了。 二&#…...

DevExpress WinForms HeatMap组件,一个高度可自定义热图控件!

通过DevExpress WinForms可以为Windows Forms桌面平台提供的高度可定制的热图UI组件&#xff0c;体验DevExpress的不同之处。 DevExpress WinForms有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。同时能完美构建流畅、美观且易于使用的应用程…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...