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

曲面(弧面、柱面)展平(拉直)瓶子标签识别ocr

瓶子或者柱面在做字符识别的时候由于变形,识别效果是很不好的

或者是检测瓶子表面缺陷的时候效果也没有展平的好

下面介绍两个项目,关于曲面(弧面、柱面)展平(拉直)

项目一:通过识别曲面的6个点展开

图1 

如 图1所示,通过A、B、C、D、E、F六个点,对柱面展成平面,对应公式可参考下图(图2)

用这个项目的前提是,需要找到这6个点,和通过机器视觉的算法或者是深度学习的算法来实现。 

 图2

1、 项目一代码

import cv2
import numpy as npBLACK_COLOR = (0, 0, 0)
WHITE_COLOR = (255, 255, 255)
YELLOW_COLOR = (0, 255, 255)
RED_COLOR = (0, 0, 255)class Line(object):def __init__(self, point1, point2):"""For line formula y(x) = k * x + b, calc k and b paramsIf the line is vertical, set "vertical" attr to True and save "x" position of the line"""self.point1 = point1self.point2 = point2self.vertical = Falseself.fixed_x = Noneself.k = Noneself.b = None# cached angle propsself.angle = Noneself.angle_cos = Noneself.angle_sin = Noneself.set_line_props(point1, point2)def is_vertical(self):return self.verticaldef set_line_props(self, point1, point2):if point2[0] - point1[0]:self.k = float(point2[1] - point1[1]) / (point2[0] - point1[0])self.b = point2[1] - self.k * point2[0]k_normal = - 1 / self.kelse:self.vertical = Trueself.fixed_x = point2[0]k_normal = 0self.angle = np.arctan(k_normal)self.angle_cos = np.cos(self.angle)self.angle_sin = np.sin(self.angle)def get_x(self, y):if self.is_vertical():return self.fixed_xelse:return int(round(float(y - self.b) / self.k))def get_y(self, x):return self.k * x + self.bclass LabelUnwrapper(object):COL_COUNT = 30ROW_COUNT = 20def __init__(self, src_image=None, pixel_points=None, percent_points=None):"""Point lists are lists of 6 points - [A, B, C, D, E, F]:param pixel_points: List[Tuple] Points, whose coordinates specified as pixels:param percent_points: List[Tuple] Points, whose coordinates specified as fraction of image width/heightIn both cases points represent figure below:|        |                  |        ||    B   |                  A        C| /    \ |                  | \    / |A        C                  |   B    ||        |                  |        ||        |       OR         |        ||        |                  |        |F        D                  F        D| \    / |                  | \    / ||   E    |                  |   E    ||        |                  |        |So, A-B-C-D-E-F-A polygon represent raw wine label on bottle"""self.src_image = src_imageself.width = self.src_image.shape[1]self.height = src_image.shape[0]self.dst_image = Noneself.points = pixel_pointsself.percent_points = percent_pointsself.point_a = None  # top leftself.point_b = None  # top centerself.point_c = None  # top rightself.point_d = None  # bottom rightself.point_e = None  # bottom centerself.point_f = None  # bottom leftself.center_line = Noneself.load_points()def load_points(self):if self.points is None:points = []for point in self.percent_points:x = int(point[0] * self.width)y = int(point[1] * self.height)points.append((x, y))self.points = pointsself.points = np.array(self.points)(self.point_a, self.point_b, self.point_c,self.point_d, self.point_e, self.point_f) = self.pointscenter_top = (self.point_a + self.point_c) / 2center_bottom = (self.point_d + self.point_f) / 2self.center_line = Line(center_bottom, center_top)if not len(self.points) == 6:raise ValueError("Points should be an array of 6 elements")def unwrap(self, interpolate=False):source_map = self.calc_source_map()if interpolate:self.unwrap_label_interpolation(source_map)else:self.unwrap_label_perspective(source_map)return self.dst_imagedef calc_dest_map(self):width, height = self.get_label_size()dx = float(width) / (self.COL_COUNT - 1)dy = float(height) / (self.ROW_COUNT - 1)rows = []for row_index in range(self.ROW_COUNT):row = []for col_index in range(self.COL_COUNT):row.append([int(dx * col_index),int(dy * row_index)])rows.append(row)return np.array(rows)def unwrap_label_interpolation(self, source_map):"""Unwrap label using interpolation - more accurate method in terms of quality"""from scipy.interpolate import griddatawidth, height = self.get_label_size()dest_map = self.calc_dest_map()grid_x, grid_y = np.mgrid[0:width - 1:width * 1j, 0:height - 1:height * 1j]destination = dest_map.reshape(dest_map.size // 2, 2)source = source_map.reshape(source_map.size // 2, 2)grid_z = griddata(destination, source, (grid_x, grid_y), method='cubic')map_x = np.append([], [ar[:, 0] for ar in grid_z]).reshape(width, height)map_y = np.append([], [ar[:, 1] for ar in grid_z]).reshape(width, height)map_x_32 = map_x.astype('float32')map_y_32 = map_y.astype('float32')warped = cv2.remap(self.src_image, map_x_32, map_y_32, cv2.INTER_CUBIC)self.dst_image = cv2.transpose(warped)def unwrap_label_perspective(self, source_map):"""Unwrap label using transform, unlike unwrap_label_interpolation doesn't require scipy"""width, height = self.get_label_size()self.dst_image = np.zeros((height, width, 3), np.uint8)dx = float(width) / (self.COL_COUNT - 1)dy = float(height) / (self.ROW_COUNT - 1)dx_int = int(np.ceil(dx))dy_int = int(np.ceil(dy))for row_index in range(self.ROW_COUNT - 1):for col_index in range(self.COL_COUNT - 1):src_cell = (source_map[row_index][col_index],source_map[row_index][col_index + 1],source_map[row_index + 1][col_index],source_map[row_index + 1][col_index + 1])dst_cell = np.int32([[0, 0], [dx, 0], [0, dy], [dx, dy]])M = cv2.getPerspectiveTransform(np.float32(src_cell), np.float32(dst_cell))dst = cv2.warpPerspective(self.src_image, M, (dx_int, dy_int))x_offset = int(dx * col_index)y_offset = int(dy * row_index)self.dst_image[y_offset:y_offset + dy_int,x_offset:x_offset + dx_int] = dstdef get_roi_rect(self, points):max_x = min_x = points[0][0]max_y = min_y = points[0][1]for point in points:x, y = pointif x > max_x:max_x = xif x < min_x:min_x = xif y > max_y:max_y = yif y < min_y:min_y = yreturn np.array([[min_x, min_y],[max_x, min_y],[max_x, max_y],[min_x, max_y]])def get_roi(self, image, points):rect = self.get_roi_rect(points)return image[np.floor(rect[0][1]):np.ceil(rect[2][1]),np.floor(rect[0][0]):np.ceil(rect[1][0])]def calc_source_map(self):top_points = self.calc_ellipse_points(self.point_a, self.point_b, self.point_c,self.COL_COUNT)bottom_points = self.calc_ellipse_points(self.point_f, self.point_e, self.point_d,self.COL_COUNT)rows = []for row_index in range(self.ROW_COUNT):row = []for col_index in range(self.COL_COUNT):top_point = top_points[col_index]bottom_point = bottom_points[col_index]delta = (top_point - bottom_point) / float(self.ROW_COUNT - 1)point = top_point - delta * row_indexrow.append(point)rows.append(row)return np.array(rows)def draw_mesh(self, color=RED_COLOR, thickness=1):mesh = self.calc_source_map()for row in mesh:for x, y in row:point = (int(round(x)), int(round(y)))cv2.line(self.src_image, point, point, color=color, thickness=thickness)def draw_poly_mask(self, color=WHITE_COLOR):cv2.polylines(self.src_image, np.int32([self.points]), 1, color)def draw_mask(self, color=WHITE_COLOR, thickness=1, img=None):"""Draw mask, if image not specified - draw to source image"""if img is None:img = self.src_imagecv2.line(img, tuple(self.point_f.tolist()), tuple(self.point_a.tolist()), color, thickness)cv2.line(img, tuple(self.point_c.tolist()), tuple(self.point_d.tolist()), color, thickness)self.draw_ellipse(img, self.point_a, self.point_b, self.point_c, color, thickness)self.draw_ellipse(img, self.point_d, self.point_e, self.point_f, color, thickness)def get_label_contour(self, color=WHITE_COLOR, thickness=1):mask = np.zeros(self.src_image.shape)self.draw_mask(color, thickness, mask)return maskdef get_label_mask(self):"""Generate mask of the label, fully covering it"""mask = np.zeros(self.src_image.shape)pts = np.array([[self.point_a, self.point_c, self.point_d, self.point_f]])cv2.fillPoly(mask, pts, WHITE_COLOR)self.draw_filled_ellipse(mask, self.point_a, self.point_b, self.point_c, True)self.draw_filled_ellipse(mask, self.point_f, self.point_e, self.point_d, False)return maskdef draw_ellipse(self, img, left, top, right, color=WHITE_COLOR, thickness=1):"""Draw ellipse using opencv function"""is_arc, center_point, axis, angle = self.get_ellipse_params(left, top, right)if is_arc:start_angle, end_angle = 0, 180else:start_angle, end_angle = 180, 360cv2.ellipse(img, center_point, axis, angle, start_angle, end_angle, color, thickness)def draw_filled_ellipse(self, img, left, top, right, is_top=False):is_arc, center_point, axis, angle = self.get_ellipse_params(left, top, right)if is_arc ^ is_top:color = WHITE_COLORelse:color = BLACK_COLORcv2.ellipse(img, center_point, axis, angle, 0, 360, color=color, thickness=-1)def get_ellipse_params(self, left, top, right):center = (left + right) / 2center_point = tuple(map(lambda x: int(np.round(x)), center.tolist()))axis = (int(np.linalg.norm(left - right) / 2), int(np.linalg.norm(center - top)))x, y = left - rightangle = np.arctan(float(y) / x) * 57.296is_arc = Falseif (top - center)[1] > 0:is_arc = Truereturn is_arc, center_point, axis, angledef calc_ellipse_points(self, left, top, right, points_count):center = (left + right) / 2# get ellipse axisa = np.linalg.norm(left - right) / 2b = np.linalg.norm(center - top)# get start and end anglesif (top - center)[1] > 0:delta = np.pi / (points_count - 1)else:delta = - np.pi / (points_count - 1)cos_rot = (right - center)[0] / asin_rot = (right - center)[1] / apoints = []for i in range(points_count):phi = i * deltadx, dy = self.get_ellipse_point(a, b, phi)x = round(center[0] + dx * cos_rot - dy * sin_rot)y = round(center[1] + dx * sin_rot + dy * cos_rot)points.append([x, y])points.reverse()return np.array(points)def get_ellipse_point(self, a, b, phi):"""Get ellipse radius in polar coordinates"""return a * np.cos(phi), b * np.sin(phi)def get_label_size(self):top_left = self.point_atop_right = self.point_cbottom_right = self.point_dbottom_left = self.point_fwidth1 = np.linalg.norm(top_left - top_right)width2 = np.linalg.norm(bottom_left - bottom_right)avg_width = int((width1 + width2) * np.pi / 4)height1 = np.linalg.norm(top_left - bottom_left)height2 = np.linalg.norm(top_right - bottom_right)avg_height = int((height1 + height2) / 2)return avg_width, avg_heightif __name__ == '__main__':shape = {"tag": "label", "shape": [{"x": 0.012232142857142842, "y": 0.2219140625},{"x": 0.48655701811449864, "y": 0.14404355243445227},{"x": 0.9632539682539681, "y": 0.2171875},{"x": 0.9466567460317459, "y": 0.7276953125},{"x": 0.48447501824501454, "y": 0.7952298867391453},{"x": 0.023134920634920626, "y": 0.7258984375}]}points = []for point in shape['shape']:points.append([point['x'], point['y']])imcv = cv2.imread('image.jpg', cv2.IMREAD_UNCHANGED)unwrapper = LabelUnwrapper(src_image=imcv, percent_points=points)dst_image = unwrapper.unwrap()for point in unwrapper.points:cv2.line(unwrapper.src_image, tuple(point), tuple(point), color=YELLOW_COLOR, thickness=3)# unwrapper.draw_mesh()cv2.imwrite("image_with_mask.png", imcv)cv2.imwrite("unwrapped.jpg", dst_image)

2、原始代码github地址库:

GitHub - Nepherhotep/unwrap_labels: Algorithm to unwrap labels using edge markers

项目二:对项目一的升级版,实现深度学习曲面标签位置,并进行字符识别

1、通过训练掩膜图像,获得模型后,自动计算6个点的位置

图3 掩膜图像

 

图5 深度学习后找到的六个点

 

2、将弧映射至曲面 

自己拿了矿泉水瓶做的实验

 图6 网格圆柱投影

3、进行展开

 

 图7 展开后效果图

展开前字符识别效果很不好

 图8 未展开直接识别字符

 

图9 展开后字符全部识别出来 

 图8和图9用的百度飞桨做的字符识别,对中文识别效果很好,项目用到的pytesseract字符库识别效果非常不好,对于广告体的中文字无法识别。

展开流程图

图10 展开流程图 

 4、项目二github地址:

GitHub - AntoninLeroy/wine_label_reader_toolkit: Computer vision project to read a label on a wine bottle using tensorflow, OpenCV and Tesseract.

项目三依赖的库

Flask==2.0.2
Flask_Cors==3.0.10
imutils==0.5.4
keras==2.8.0
numpy==1.21.5
opencv_python==4.5.5.62
Pillow==9.0.1
pytesseract==0.3.8
scikit_learn==1.0.2
scipy==1.7.3
tensorflow==2.8.0
tqdm==4.62.3

特别说明:项目二用了深度学习,使用框架,依赖gpu,无gpu无法运行,没有gpu的同学可以看项目三,项目三是本人改进的版本

项目三:自己通过视觉算法或者ps生成掩膜图像放置对应的位置即可

1、项目三基础代码

import cv2
import numpy as np
from showVision import *
import json
#日期:2023年8月10日
#作者:大胡子大叔
#托管:csdn
#程序功能:通过掩膜图像和原始图像,对柱形图进行拉伸,或者说是展开,曲面展成平面图形
#之所以修改,是因为cpu电脑无法运行tensorflow和keras的库一直报错,所以直接去掉了,没有用深度学习对识别位置进行检测
#可以通过传统的二维算法将位置提取出来,然后再展开即可
#重要的算法是展开
#倾斜的图像也可以矫正
#原始图像路径
img = cv2.imread("./img/train_and_valid/X/400.png")#遮罩图像路径
mask = cv2.imread("./img/train_and_valid/Y/400.png", 0)#得到遮罩后的图像
image = cv2.bitwise_and(img, img, mask=mask)label = labelVision()
mesh,unwrapped=label.readLabels(mask, img)# 最近邻插值法缩放# 缩放到原来的四分之一
image_scale = cv2.resize(image, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)
mesh_scale = cv2.resize(mesh, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)
unwrapped_scale = cv2.resize(unwrapped, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)
# 显示结果图像
#因为图片尺寸过大,需要缩放窗口,缩放窗口以后,显示窗口有时看不见,所以需要设置一下显示窗口的位置
cv2.imshow('cut', image_scale)
#设置窗口的位置
cv2.moveWindow('cut',100,100)
cv2.waitKey(0)
cv2.imshow('mesh', mesh_scale)
cv2.moveWindow('mesh',100,100)
cv2.waitKey(0)
cv2.imshow('unwrapped', unwrapped_scale)
cv2.moveWindow('unwrapped',100,100)
cv2.waitKey(0)
cv2.destroyAllWindows()

 2、项目三依赖的库

imutils
numpy
opencv_python

如果不做字符识别可不安装下面的库
pytesseract


曲面(弧面、柱面)展平(拉直)需要自己做一个遮罩层
此代码主要是为了方便嫁接使用
自己用视觉算法识别遮罩即可进行嫁接
里面代码去掉了原始程序对gpu的依赖(即自动检测遮罩层位置,所以需要自己做遮罩层)
如果就想用深度学习识别,不想去掉的话,可以访问原始代码地址
https://github.com/AntoninLeroy/wine_label_reader_toolkit
原始代码包含自动识别、展开、字符识别整个流程
如果只想要柱面展开代码,请自行下载
本里面包含两个版本,一个版本包含字符识别,一个版本不包含字符识别 

3、项目三代码下载地址

 https://download.csdn.net/download/sunnyrainflower/88228306


扩展一:平面变曲面(平面向柱面投影)

图11 

参考链接:柱面投影介绍与python实现(一)_zwx1995zwx的博客-CSDN博客 

实现代码

from skimage.io import imread, imshow ,imsave
from skimage.transform import resize
import math
import numpy as npimg = imread('img.jpg')
img = (resize(img , [1000,800])*255).astype(np.uint8)###圆柱投影
def cylindrical_projection(img , f) :rows = img.shape[0]cols = img.shape[1]#f = cols / (2 * math.tan(np.pi / 8))blank = np.zeros_like(img)center_x = int(cols / 2)center_y = int(rows / 2)for  y in range(rows):for x in range(cols):theta = math.atan((x- center_x )/ f)point_x = int(f * math.tan( (x-center_x) / f) + center_x)point_y = int( (y-center_y) / math.cos(theta) + center_y)if point_x >= cols or point_x < 0 or point_y >= rows or point_y < 0:passelse:blank[y , x, :] = img[point_y , point_x ,:]return blankwaved_img = cylindrical_projection(img,500)
imshow(waved_img)

 拓展二:弧面表拉直(展平)

 图12

 图 13

 用了项目三中的代码将弧形表进行展开,发现两侧的刻度过度拉伸,直接用的话效果不是很好,还需对代码进行调整才能使用,不过为弧度表的表盘识别提供了新方向。

------------------------------------------------------------

声明 | 未经允许,禁止转载,谢谢合作!

作者 | 大胡子大叔

出品 | CSDN

-------------------------------------------------------------

 

相关文章:

曲面(弧面、柱面)展平(拉直)瓶子标签识别ocr

瓶子或者柱面在做字符识别的时候由于变形&#xff0c;识别效果是很不好的 或者是检测瓶子表面缺陷的时候效果也没有展平的好 下面介绍两个项目&#xff0c;关于曲面&#xff08;弧面、柱面&#xff09;展平&#xff08;拉直&#xff09; 项目一&#xff1a;通过识别曲面的6个点…...

知识继承概述

文章目录 知识继承第一章 知识继承概述1.背景介绍第一页 背景第二页 大模型训练成本示例第三页 知识继承的动机 2.知识继承的主要方法 第二章 基于知识蒸馏的知识继承预页 方法概览 1.知识蒸馏概述第一页 知识蒸馏概述第二页 知识蒸馏第三页 什么是知识第四页 知识蒸馏的核心目…...

深度剖析数据在内存中的存储

目录 一、数据类型介绍 类型的基本归类 1.整形家族 2.浮点数家族 3.构造类型 &#xff08;自定义类型&#xff09; 4.指针类型 5.空类型 二、整形在内存中的存储 1.原码、反码、补码 1.1原码 1.2反码 1.3补码 1.4计算规则 2 .大小端介绍 三、浮点型在内存中的存…...

【ARM Linux 系统稳定性分析入门及渐进10 -- GDB 初始化脚本介绍及使用】

文章目录 gdb 脚本介绍gdb 初始化脚本使用启动 gdb 的时候自动执行脚本gdb运行期间执行命令脚本 gdb 脚本介绍 GDB脚本是一种使用GDB命令语言编写的脚本&#xff0c;可以用来自动化一些常见的调试任务。这些脚本可以直接在GDB中运行&#xff0c;也可以通过GDB的-x参数或source…...

AQS源码解读

文章目录 前言一、AQS是什么&#xff1f;二、解读重点属性statehead、tail 同步变量竞争acquire 同步变量释放 总结 前言 AQS是AbstractQueuedSynchronizer的缩写&#xff0c;也是大神Doug Lea的得意之作。今天我们来进行尽量简化的分析和理解性的代码阅读。 一、AQS是什么&am…...

QT实现天气预报

1. MainWindow类设计的成员变量和方法 public: MainWindow(QWidget* parent nullptr); ~MainWindow(); protected: 形成文本菜单来用来右键关闭窗口 void contextMenuEvent(QContextMenuEvent* event); 鼠标被点击之后此事件被调用 void mousePressEvent(QMouseEv…...

【马蹄集】第二十三周——进位制专题

进位制专题 目录 MT2186 二进制&#xff1f;不同&#xff01;MT2187 excel的烦恼MT2188 单条件和MT2189 三进制计算机1MT2190 三进制计算机2 MT2186 二进制&#xff1f;不同&#xff01; 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目…...

[足式机器人]Part3 变分法Ch01-1 数学预备知识——【读书笔记】

本文仅供学习使用 本文参考&#xff1a; 《变分法基础-第三版》老大中 《变分学讲义》张恭庆 《Calculus of Variations of Optimal Control Theory》-变分法和最优控制论-Daneil Liberzon Ch01-1 数学基础-预备知识1 1 数学基础-预备知识1.1 泰勒公式1.1.1 一元函数的泰勒公式…...

计算机网络----CRC冗余码的运算

目录 1. 冗余码的介绍及原理2. CRC检验编码的例子3. 小练习 1. 冗余码的介绍及原理 冗余码是用于在数据链路层的通信链路和传输数据过程中可能会出错的一种检错编码方法&#xff08;检错码&#xff09;。原理&#xff1a;发送发把数据划分为组&#xff0c;设每组K个比特&#…...

将Nginx源码数组结构(ngx_array.c)和内存池代码单独编译运行,附代码

在上面一篇的基础上把Nginx源码数组结构也摘录下来&#xff0c;也增加了测试代码&#xff0c;编译运行。 https://blog.csdn.net/katerdaisy/article/details/132358883 《将nginx内存池代码单独编译运行&#xff0c;了解nginx内存池工作原理&#xff0c;附代码》 核心代码&…...

java forEach中不能使用break和continue的原因

1.首先了解break和continue的使用范围和作用 1.1使用范围 break适用范围&#xff1a;只能用于switch或者是循环语句中。当然可以用于增强for循环。 continue适用范围: 用于循环语句中。 1.2作用 break: 1. break用于switch语句的作用是结束一个switch语句。 2. break用于循…...

[杂项]水浒英雄谱系列电影列表

年份 片名 导演 主演 2006-01-01 母夜叉孙二娘 张建亚 周海媚 、 莫少聪 、 于承惠 [1] 2008-01-01 碧瑶霜迷案 黄祖权 陈龙 、 陈德容 、 翁家明 [7] 2008-05-09 青面兽杨志 张建亚 吕良伟 、 计春华 、 孟广美 [2] 2008-05-09 扈三娘与矮脚虎王英 张建亚 曾宝仪 、 郭德纲 、…...

6.RocketMQ之索引文件ConsumeQueue

本文着重分析为consumequeue/topic/queueId目录下的索引文件。 1.ConsumeQueueStore public class ConsumeQueueStore {protected final ConcurrentMap<String>, ConcurrentMap<Integer>, ConsumeQueueInterface>> consumeQueueTable;public boolean load(…...

【C++学习手札】一文带你认识C++虚继承​​

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f340;本文前置知识&#xff1a;C虚函数&#xff08;很重要&#xff0c;内部剖析&#xff09; ♈️今日夜电波&#xff1a;僕らのつづき—柊優花 1:06 ━━━━━━️&#x1f49f;──────── 3:51 …...

神经网络基础-神经网络补充概念-63-残差网络

概念 残差网络&#xff08;Residual Network&#xff0c;ResNet&#xff09;是一种深度卷积神经网络结构&#xff0c;旨在解决深层网络训练中的梯度消失和梯度爆炸问题&#xff0c;以及帮助训练非常深的网络。ResNet 在2015年被提出&#xff0c;其核心思想是引入了"残差块…...

【从0开始学架构笔记】01 基础架构

文章目录 一、架构的定义1. 系统与子系统2. 模块与组件3. 框架与架构4. 重新定义架构 二、架构设计的目的三、复杂度来源&#xff1a;高性能1. 单机复杂度2. 集群复杂度2.1 任务分配2.2 任务分解&#xff08;微服务&#xff09; 四、复杂度来源&#xff1a;高可用1. 计算高可用…...

vue3+ts+vite使用el-breadcrumb实现面包屑组件,实现面包屑过渡动画

简介 使用 element-plus 的 el-breadcrumb 组件&#xff0c;实现根据页面路由动态生成面包屑导航&#xff0c;并实现面包屑导航的切换过渡动画 一、先看效果加粗样式 1.1 静态效果 1.2 动态效果 二、全量代码 <script lang"ts" setup> import { ref, watch…...

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,数组)四(116)

需求&#xff1a;&#xff1a;前端根据后端的返回数据&#xff1a;画统计图&#xff1b; 1.动态获取地域数据以及数据中的平均值&#xff0c;按照平均值降序排序&#xff1b; 说明&#xff1a; X轴是动态的&#xff0c;有对应区域数据则展示&#xff1b; X轴 区域数据降序排序…...

Chrome命令行开关

Electron 支持的命令行开关 –client-certificatepath 设置客户端的证书文件 path . –ignore-connections-limitdomains 忽略用 , 分隔的 domains 列表的连接限制. –disable-http-cache 禁止请求 HTTP 时使用磁盘缓存. –remote-debugging-portport 在指定的 端口 通…...

元宇宙赛道加速破圈 和数软件抓住“元宇宙游戏”发展新风口

当下海外游戏市场仍然具备较大的增长空间。据机构预测&#xff0c;至2025年全球移动游戏市场规模将达1606亿美元&#xff0c;对应2020-2025年复合增长率11&#xff05;。与此同时&#xff0c;随着元宇宙概念持续升温&#xff0c;国内外多家互联网巨头纷纷入场。行业分析平台New…...

Vue的鼠标键盘事件

Vue的鼠标键盘事件 原生 鼠标事件(将v-on简写为) click // 点击 dblclick // 双击 mousedown // 按下 mousemove // 移动 mouseleave // 离开 mouseout // 移出 mouseenter // 进入 mouseover // 鼠标悬浮mousedown.left 键盘事件 keydown //键盘按下时触发 keypress …...

Bytebase 2.6.0 - ​支持通过 LDAP 配置 SSO,支持 RisingWave 数据库

&#x1f680; 新功能 支持通过 LDAP 配置 SSO。支持增加多个只读连接。Schema 模版支持列类型约束。支持 RisingWave 数据库。库表同步功能支持 TiDB。数据脱敏功能支持 SQL Server。SQL 审核 CI 功能支持 Azure DevOps。 &#x1f384; 改进 支持设置数据库的环境与所属实…...

C# 读取pcd、ply点云文件数据

最近研究了下用pcl读取点云数据&#xff0c;又做了个C#的dll&#xff0c;方便读取&#xff0c;同样这个dll基于pcl 最新版本1.13.1版本开发。 上次做的需要先得到点云长度&#xff0c;再获取数据。这次这个定义了一个PointCloudXYZ类来存数据。将下面的dll拷贝到可执行目录下&a…...

LeetCode1387 将整数按权重排序

思路 首先是这种计算权重的方式很有可能出现重复&#xff0c;所以需要记忆化搜索记忆化搜索&#xff1a;先查表再计算&#xff0c;先存表再返回。将整数 x 和计算的权重分别存储数组的0和1的位置重写compare将数组排序按规则排序返回结果 代码 class Solution {private Hash…...

正则表达式--Intellij IDEA常用的替换

原文网址&#xff1a;正则表达式--Intellij IDEA常用的替换_IT利刃出鞘的博客-CSDN博客 简介 本文介绍IDEA使用正则表达式进行替换时的常用的一些示例。 根据注释加注解 需求 将 /*** abc*/ 改为&#xff1a; /*** abc*/ ApiModelOperation("abc") 方法 选…...

前端如何安全的渲染HTML字符串?

在现代的Web 应用中&#xff0c;动态生成和渲染 HTML 字符串是很常见的需求。然而&#xff0c;不正确地渲染HTML字符串可能会导致安全漏洞&#xff0c;例如跨站脚本攻击&#xff08;XSS&#xff09;。为了确保应用的安全性&#xff0c;我们需要采取一些措施来在安全的环境下渲染…...

C++学习第十四天----for循环

1.递增/递减运算符和指针 将*和同时用于指针的优先级&#xff1f; 答&#xff1a;前缀递增&#xff0c;前缀递减和解除引用运算符的优先级相同&#xff0c;以从右到左的方式进行结合&#xff1b;后缀递增和后缀递减的优先级相同&#xff0c;但比前缀运算符的优先级高&#xff0…...

快速解决在进入浏览器时,明明连接了网络,但是显示你尚未连接,代理服务器可能有问题。

在进入浏览器时&#xff0c;明明连接了网络&#xff0c;但是显示你尚未连接&#xff0c;代理服务器可能有问题&#xff0c;如下图。 一般情况下&#xff0c;可能是因为你使用了某些VPN&#xff0c;然后VPN使用时修改了你的网络设置&#xff0c;我们可以通过以下方法快速解决。 …...

TypeScript入门指南

TypeScript学习总结内容目录&#xff1a; TypeScript概述 TypeScript特性。Javascript与TypeScript的区别 * TypeScript安装及其环境搭建TypeScript类型声明 * 单个类型声明&#xff0c;多个类型声明 * 任意类型声明 * 函数类型声明 * unknown类型…...

excel中定位条件,excel中有哪些数据类型、excel常见错误值、查找与替换

一、如何定位条件 操作步骤&#xff1a;开始 - 查找和选择 - 定位条件&#xff08;ctrl G 或 F5&#xff09; 注&#xff1a;如果F5不可用&#xff0c;可能是这个快捷键被占用了 案例&#xff1a;使用定位条件选择取余中空单元格&#xff0c;填入100&#xff0c;按组合键ct…...

19c_ogg搭建

1.环境介绍 源端&#xff1a;192.168.56.101 目标端&#xff1a;192.168.56.100 背景&#xff1a;数据从主库cdb主机定位&#xff0c;同步到从库 2.配置ogg 2.1 开启归档、强制日志、补充日志 --ogg 主备都需要配置 SQL> alter database archivelog; SQL> alter databa…...

网络通信原理网络层TCP/IP协议(第四十三课)

1.什么是TCP/IP 目前应用广泛的网络通信协议集 国际互联网上电脑相互通信的规则、约定。 2.主机通信的三要素 IP地址:用来标识一个节点的网络地址(区分网络中电脑身份的地址,如人有名字) 子网掩码:配合IP地址确定网络号 IP路由:网关的地址,网络的出口 3.IP地址 …...

yolov5封装进ros系统

一&#xff0c;要具备ROS环境 ROS环境搭建可以参考我之前的文章 ROS参考文章1 ROS参考文章2   建立ROS工作空间 ROS系统由自己的编译空间规则。 cd 你自己想要的文件夹&#xff08;我一般是home目录&#xff09; mkdir -p (你自己的文件夹名字&#xff0c;比如我是yolov5…...

Flowable 源码目录结构

title: Flowable 源码目录结构 date: 2023-8-17 23:47:20 tags: - Flowable 下载源码 下载地址&#xff1a;flowable/flowable-engine at flowable-6.7.2 (github.com) Git 下载方式&#xff1a;git clone gitgithub.com:flowable/flowable-engine.git 切换分支 git checkout -…...

科大讯飞星火模型申请与chatgpt 3.5模型以及new bing的对比

科大讯飞星火模型 申请科大讯飞星火认知大模型账号科大讯飞星火认知大模型使用1.界面介绍2. 在编程能力上与chatgpt 3.5对比科大讯飞星火模型chatgpt 3.5模型 3. 在图片生成能力上与new bing对比 总结 申请科大讯飞星火认知大模型账号 注册网址&#xff1a; 科大讯飞星火认知大…...

无涯教程-TensorFlow - 分布式计算

本章将重点介绍如何开始使用分布式TensorFlow&#xff0c;目的是帮助开发人员了解重复出现的基本分布式TF概念&#xff0c;如TF服务器。无涯教程将使用Jupyter Notebook分布式TensorFlow。 第1步 - 导入分布式计算必需的必要模块- import tensorflow as tf 第2步 - …...

python+django+mysql项目实践五(信息搜索)

python项目实践 环境说明: Pycharm 开发环境 Django 前端 MySQL 数据库 Navicat 数据库管理 信息搜素 输入内容进行搜索,内容有文本类和时间类 文本类需要模糊搜索,包含即检索 时间类需要选取时间范围内的内容 views 利用Q完成对指定内容的检索 检索后按检索内容更新…...

Python Opencv实践 - 图像透射变换

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) rows,cols img.shape[:2] print(rows,cols)#opencv中的透射变换&#xff0c;需要一个3x3透射变换矩阵 #这个矩阵可以通过…...

SpringBoot + Vue 微人事项目(第二天)

昨天做了微人事登录的前端页面和后端接口&#xff0c;实现了前后端接口的对接&#xff0c;输入正确的用户名和密码之后&#xff0c;成功的跳转到home页。现在要做的就是Home页的Title制作 Home页的title制作 使用Element UI中的Container布局容器 复制的代码如下&#xff0c…...

【AIGC】 快速体验Stable Diffusion

快速体验Stable Diffusion 引言一、安装二、简单使用2.1 一句话文生图2.2 详细文生图 三、进阶使用 引言 stable Diffusion是一款高性能的AI绘画生成工具&#xff0c;相比之前的AI绘画工具&#xff0c;它生成的图像质量更高、运行速度更快&#xff0c;是AI图像生成领域的里程碑…...

Python入门【动态添加属性和方法、正则表达式概述、match函数的使用、常用匹配符、限定符 、限定符使用示例】(二十九)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…...

《Go 语言第一课》课程学习笔记(四)

构建模式&#xff1a;Go Module 的 6 类常规操作 为当前 module 添加一个依赖 我们如何为一个 Go Module 添加一个新的依赖包呢&#xff1f; 如果我们要为项目增加一个新依赖&#xff1a;github.com/google/uuid&#xff0c;我们首先会更新源码&#xff1a;package mainimpor…...

制定建立商务模式财务及企业管理信息系统的解决方案

1、调查企业对 Internet 的需求&#xff0c;并制定全面规划。由于电子商务的范围相当 广泛&#xff0c;企业在实施电子商务模式财务及企业管理信息系统时&#xff0c;应先调查哪些对于企 业的收益较大&#xff0c;然后进行全面规划&#xff0c;即规划信息化基本平台、后台企业…...

UE Json Operate 解析嵌套数组

演示如何使用 DTJsonOperate 插件&#xff0c;在蓝图中解析嵌套数组。 比如这个Json {"name": [[[1, 2]],[3, 4],[5, 6]] } 操作演示 最后打印 本功能需要插件支持&#xff0c;插件下载地址。...

sd-webui安装comfyui扩展

文章目录 导读ComfyUI 环境安装1. 安装相关组件2. 启动sd-webui3. 访问sd-webui 错误信息以及解决办法 导读 这篇文章主要给大家介绍如何在sd-webui中来安装ComfyUI插件 ComfyUI ComfyUI是一个基于节点流程式的stable diffusion的绘图工具&#xff0c;它集成了stable diffus…...

Apache Doris 2.0.0 版本正式发布:盲测性能 10 倍提升,更统一多样的极速分析体验

亲爱的社区小伙伴们&#xff0c;我们很高兴地向大家宣布&#xff0c;Apache Doris 2.0.0 版本已于 2023 年 8 月 11 日正式发布&#xff0c;有超过 275 位贡献者为 Apache Doris 提交了超过 4100 个优化与修复。 在 2.0.0 版本中&#xff0c;Apache Doris 在标准 Benchmark 数…...

LeetCode235. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先 文章目录 [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)一、题目二、题解方法一&#xff1a;递归方法二&#xff1a;迭代 一、题目 给定一个二叉搜索树, 找到该树中两个指定…...

设计模式——建造者(Builder)模式

建造者模式&#xff08;Builder Pattern&#xff09;&#xff0c;又叫生成器模式&#xff0c;是一种对象构建模式 它可以将复杂对象的建造过程抽象出来&#xff0c;使这个抽象过程的不同实现方法可以构造出不同表现的对象。建造者模式是一步一步创建一个复杂的对象&#xff0c;…...

Java课题笔记~ SpringBoot概述

问题导入 学习了SpringBoot入门案例之后&#xff0c;感觉对比SpringMVC哪一个更加方便简洁&#xff1f; SpringBoot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化Spring应用的初始搭建以及开发过程 Spring程序缺点 配置繁琐 依赖设置繁琐 SpringBoot程序…...

python优雅地爬虫!

背景 我需要获得新闻&#xff0c;然后tts&#xff0c;在每天上班的路上可以听一下。具体的方案后期我也会做一次分享。先看我喜欢的万能的老路&#xff1a;获得html内容-> python的工具库解析&#xff0c;获得元素中的内容&#xff0c;完成。 好家伙&#xff0c;我知道我爬…...