AI聊天伴侣的语料采集大揭秘:OpenCV如何轻松识别聊天图片?

最近,负责元宇宙中AI聊天伴侣的语料数据采集,这些数据主要用于AI虚拟角色聊天的训练和测试。虽然语料获取有多种渠道,但由于部分数据涉及隐私,这里就不多说了(感兴趣的朋友可以私聊我)。今天,我将详细讲解如何利用OpenCV轻松识别真实的聊天图片。

在这个过程中,我主要涉及了一系列操作,包括OpenCV如何读取PDF多个分页图片、如何对图片进行水印过滤和异常文字剔除、如何识别聊天文本框和聊天角色、以及如何提取颜色等关键步骤。

通过OpenCV的强大功能,实现对聊天图片的智能识别和处理。这些技术操作不仅能构建了一个高质量的语料库,而且为AI虚拟角色的训练提供了可靠的基础。

导入第三方库:

import os
import json
import base64, re
from tqdm import tqdm
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.ocr.v20181119 import ocr_client, models
import fitz  # PyMuPDF
import numpy as np

腾讯云OCR服务识别图片所有文字

腾讯云OCR使用需要开通服务获取api密钥和id,可以白嫖使用api一千次,如何开通腾讯云使用腾讯云OCR服务,具体可以参考(这里选的是通用印刷识别 高精度版):文字识别 通用印刷体识别(高精度版)-服务端 API 文档-文档中心-腾讯云

图片:

代码:

def make_api_call(base64_str, jsn_fpath, json_data):try:cred = credential.Credential(secret_id, secret_key)httpProfile = HttpProfile()httpProfile.endpoint = "ocr.tencentcloudapi.com"clientProfile = ClientProfile()clientProfile.httpProfile = httpProfileclient = ocr_client.OcrClient(cred, "ap-guangzhou", clientProfile)req = models.GeneralAccurateOCRRequest()params = {'LanguageType': 'zh','IsPdf': True,"PdfPageNumber": 5,'ImageBase64': f'data:image/jpeg;base64,{base64_str}',# 'EnableDetectText': True}req.from_json_string(json.dumps(params))resp = client.GeneralBasicOCR(req)res = json.loads(resp.to_json_string()).get('TextDetections')print("res lenght:",len(res))json_data['TextDetections'].append(res)# breakexcept TencentCloudSDKException as err:print(err)print("len(json_data['TextDetections']):",len(json_data['TextDetections']))os.makedirs(os.path.dirname(os.path.realpath(jsn_fpath)), exist_ok=True)with open(jsn_fpath, 'w', encoding='UTF-8') as o_file:o_file.write(json.dumps(json_data, ensure_ascii=False))if __name__ == '__main__':secret_id = "密钥id"secret_key = "密钥key 通过腾讯云账号获取"jpg_fpath = '图片路径.jpg'with open(jpg_fpath, 'rb') as i_file:base64_str = base64.b64encode(i_file.read()).decode()json_data = {"TextDetections":[]}jsn_fpath = '输出结果json文件.json'make_api_call(base64_str, jsn_fpath, json_data)

输出结果:

包含多个识别结果的列表,DetectedText:识别结果的文本;Polygon:文字所在的坐标,Confidence:字体大小。

{"TextDetections": [[{"DetectedText": "这个", "Confidence": 100, "Polygon": [{"X": 633, "Y": 824}, {"X": 724, "Y": 824}, {"X": 724, "Y": 872}, {"X": 633, "Y": 872}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":2}}", "ItemPolygon": {"X": 633, "Y": 824, "Width": 91, "Height": 48}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "看看里面有几个", "Confidence": 100, "Polygon": [{"X": 403, "Y": 969}, {"X": 724, "Y": 969}, {"X": 724, "Y": 1017}, {"X": 403, "Y": 1017}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":3}}", "ItemPolygon": {"X": 403, "Y": 969, "Width": 321, "Height": 48}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "十个", "Confidence": 100, "Polygon": [{"X": 52, "Y": 1108}, {"X": 140, "Y": 1108}, {"X": 140, "Y": 1159}, {"X": 52, "Y": 1159}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":1}}", "ItemPolygon": {"X": 52, "Y": 1108, "Width": 88, "Height": 51}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "kamole", "Confidence": 89, "Polygon": [{"X": 87, "Y": 1322}, {"X": 162, "Y": 1322}, {"X": 162, "Y": 1341}, {"X": 87, "Y": 1341}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":4}}", "ItemPolygon": {"X": 87, "Y": 1322, "Width": 75, "Height": 19}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "003", "Confidence": 100, "Polygon": [{"X": 41, "Y": 1408}, {"X": 186, "Y": 1408}, {"X": 186, "Y": 1467}, {"X": 41, "Y": 1467}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":4}}", "ItemPolygon": {"X": 41, "Y": 1408, "Width": 145, "Height": 59}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "THBEEL", "Confidence": 100, "Polygon": [{"X": 41, "Y": 1448}, {"X": 97, "Y": 1448}, {"X": 97, "Y": 1480}, {"X": 41, "Y": 1480}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":4}}", "ItemPolygon": {"X": 41, "Y": 1448, "Width": 56, "Height": 32}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "2", "Confidence": 100, "Polygon": [{"X": 95, "Y": 1585}, {"X": 119, "Y": 1585}, {"X": 119, "Y": 1596}, {"X": 95, "Y": 1596}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":5}}", "ItemPolygon": {"X": 95, "Y": 1585, "Width": 24, "Height": 11}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "可以", "Confidence": 100, "Polygon": [{"X": 635, "Y": 1692}, {"X": 727, "Y": 1692}, {"X": 727, "Y": 1740}, {"X": 635, "Y": 1740}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":7}}", "ItemPolygon": {"X": 635, "Y": 1692, "Width": 92, "Height": 48}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "那就这个了", "Confidence": 100, "Polygon": [{"X": 49, "Y": 1837}, {"X": 277, "Y": 1837}, {"X": 277, "Y": 1885}, {"X": 49, "Y": 1885}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":6}}", "ItemPolygon": {"X": 49, "Y": 1837, "Width": 228, "Height": 48}, "Words": [], "WordCoordPoint": []}, {"DetectedText": "好", "Confidence": 100, "Polygon": [{"X": 678, "Y": 1978}, {"X": 729, "Y": 1978}, {"X": 729, "Y": 2027}, {"X": 678, "Y": 2027}], "AdvancedInfo": "{\"Parag\":{\"ParagNo\":8}}", "ItemPolygon": {"X": 678, "Y": 1978, "Width": 51, "Height": 49}, "Words": [], "WordCoordPoint": []}]]}

Opencv识别图片的文本轮廓

首先对图片进行二值化突出目标物体的轮廓,然后进行中值滤波除图像中的噪声,最后使用cannyPic进行边缘检测,最终返回所有轮廓坐标。(后续基于这些轮廓坐标可以确认文本所属的背景颜色,这样就能确定文本所属的角色)

def get_contours(image):srcPic = image  # 将图像转换为灰度gray = cv2.cvtColor(srcPic, cv2.COLOR_BGR2GRAY)# 自适应阈值二值化binPic = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)# 中值滤波median = cv2.medianBlur(binPic, 5)# 边缘检测cannyPic = cv2.Canny(median, 10, 200)# 找出轮廓contours, hierarchy = cv2.findContours(cannyPic, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 根据轮廓面积排序并筛选min_contour_area = 500contours = sorted(contours, key=cv2.contourArea, reverse=True)contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_contour_area]# 画出矩形框rectangles = []for i in range(min(26, len(contours))):x, y, w, h = cv2.boundingRect(contours[i])cv2.rectangle(srcPic, (x, y), (x + w, y + h), (0, 255, 0), 2)rectangles.append(((x, y), (x + w, y + h)))# 显示处理后的图像cv2.namedWindow(str("C"), cv2.WINDOW_NORMAL)cv2.resizeWindow(str("C"), 800, 1000) cv2.imshow('C', srcPic) cv2.waitKey(0)cv2.destroyAllWindows()return rectangles #返回轮廓坐标列表if __name__ == "__main__":img = cv2.imread('77.jpg') #20 31 64img = get_contours(img)

    输出结果:

初步识别到个别轮廓,到还没达到最好的效果,预想的目标是识别出所有聊天的文本框。

改进方案:

由于对图片进行二值化后,图片变成黑白像素,而聊天文本框和文字都是黑色像素的轮廓,所以将文字转换为成白色有利于减少的噪音。

代码:(get_contours方法里对图片二值化之前增加下面代码)

    # Apply thresholding to replace black pixels with white pixelshsv = cv2.cvtColor(srcPic, cv2.COLOR_BGR2HSV)# Define the lower and upper bounds for black color in HSVlower_black = np.array([0, 0, 0], dtype=np.uint8)upper_black = np.array([180, 255, 86], dtype=np.uint8)# Create a binary mask for black pixelsblack_mask = cv2.inRange(hsv, lower_black, upper_black)# Replace black pixels with white pixelssrcPic[black_mask > 0] = [255, 255, 255]

文字没转换白色像素之前的效果:

文字转换成白色后二值化结果:

虽然通过把文字转换成白色像素,减少了噪音,但还远远不够识别出所有文本框的效果。

通过morphologyEx :将图像中的物体轮廓膨胀,增加物体的面积。膨胀操作通常用于连接两个相邻的物体或填充物体的空洞

    kernel = np.ones((6, 6), np.uint8)binPic = cv2.morphologyEx(binPic, cv2.MORPH_OPEN, kernel, iterations=3)

效果:

完整识别出所有文本框轮廓

基于上述操作基本实现一个简单的聊天文本框识别,后续通过识别到的文字坐标确定它所属的文本框所在的背景颜色,就能确定文本所属的角色。

下面进一步讲解如何识别包含水印和异常文字的图片中的文本框所在位置。

原始图片:

识别结果:

通过之前的代码识别,识别结果水印基本已经剔除掉,但文本框包含了头像部分,头像并不是我们想要的部分,会影响后续坐标定位背景颜色。

通过显示中值滤波的图片发现,很明显白色头像和文本框被识别成一体了,median如下图:

解决方法:

通过在图片右侧画一条虚线,然后通过横线腐蚀来分离文本和头像(这个方法是我在处理文本框和边界融为一体后不能被识别成功时候想到的)

代码:

   #get_contours方法里添加下面代码border_size = 12pattern = np.array([0, 255] * (border_size // 2), dtype=np.uint8)# Apply the dashed line pattern to the right side of the imagebinPic[:, -border_size:] = pattern[:binPic.shape[0]]binPic = dilate_line(binPic, 'horizontal', 120, 900) #vertical
def dilate_line(binary, type='vertical', x_scale=10, y_scale=5):'''获取竖线/横线腐蚀后的二值图'''rows_z, cols_z = binary.shapeif type == 'horizontal':size = (cols_z // x_scale, 1)else:size = (1, rows_z // y_scale)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, size) eroded = cv2.erode(binary, kernel, iterations=1)  # 腐蚀dilated = cv2.dilate(eroded, kernel, iterations=1)  # 膨胀 return dilated

改进后的结果:

完整代码:

import numpy as np
import cv2def dilate_line(binary, type='vertical', x_scale=10, y_scale=5):'''获取竖线/横线腐蚀后的二值图'''rows_z, cols_z = binary.shapeif type == 'horizontal':size = (cols_z // x_scale, 1)else:size = (1, rows_z // y_scale)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, size) eroded = cv2.erode(binary, kernel, iterations=1)  # 腐蚀dilated = cv2.dilate(eroded, kernel, iterations=1)  # 膨胀 return dilateddef get_contours(image):srcPic = image  # 读取图像hsv = cv2.cvtColor(srcPic, cv2.COLOR_BGR2HSV)  # 将图像转换为HSV颜色空间# 定义在HSV颜色空间中表示黑色的范围lower_black = np.array([0, 0, 0], dtype=np.uint8)upper_black = np.array([180, 255, 86], dtype=np.uint8)# 创建二值掩模,将黑色替换为白色black_mask = cv2.inRange(hsv, lower_black, upper_black)srcPic[black_mask > 0] = [255, 255, 255]# 将图像转换为灰度gray = cv2.cvtColor(srcPic, cv2.COLOR_BGR2GRAY)# 自适应阈值二值化binPic = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)# 开运算,去除噪音kernel = np.ones((6, 6), np.uint8)binPic = cv2.morphologyEx(binPic, cv2.MORPH_OPEN, kernel, iterations=3)# 应用虚线模式到图像右侧border_size = 12pattern = np.array([0, 255] * (border_size // 2), dtype=np.uint8)binPic[:, -border_size:] = pattern[:binPic.shape[0]]# 水平膨胀操作binPic = dilate_line(binPic, 'horizontal', 120, 900)# 中值滤波median = cv2.medianBlur(binPic, 5)# 边缘检测cannyPic = cv2.Canny(median, 10, 200)# 找出轮廓contours, hierarchy = cv2.findContours(cannyPic, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 根据轮廓面积排序并筛选min_contour_area = 500contours = sorted(contours, key=cv2.contourArea, reverse=True)contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_contour_area]# 画出矩形框rectangles = []for i in range(min(26, len(contours))):x, y, w, h = cv2.boundingRect(contours[i])cv2.rectangle(srcPic, (x, y), (x + w, y + h), (0, 255, 0), 2)rectangles.append(((x, y), (x + w, y + h)))# 显示处理后的图像cv2.namedWindow(str("C"), cv2.WINDOW_NORMAL)cv2.resizeWindow(str("C"), 800, 1000) cv2.imshow('C', srcPic) cv2.waitKey(0)cv2.destroyAllWindows()print(rectangles)return rectanglesif __name__ == "__main__":img = cv2.imread('123.jpg') #20 31 64img = get_contours(img)# img_separate = get_color(img) #设置get_color 返回roi后,判断轮廓所在的颜色区域

代码中通过对面积进行排序后,使用for i in range(min(26, len(contours))) 只返回了前26最大面积的轮廓

输出结果(前26个轮廓坐标,这里没有26轮廓这么多):

[((210, 383), (901, 468)), ((550, 495), (939, 609)), ((563, 640), (945, 754)), ((26, 778), (389, 904)), ((362, 274), (749, 362)), ((174, 135), (411, 249)), ((398, 942), (715, 1011)), ((968, 495), (1080, 607)), ((968, 640), (1080, 752)), ((88, 135), (144, 206)), ((32, 139), (64, 205)), ((689, 31), (708, 86)), ((978, 66), (1008, 91)), ((148, 143), (169, 178)), ((514, 131), (539, 158))]

由于之前使用OCR识别文字已经返回了文字所在的坐标,通过这个坐标我们可以确定文本所在的轮廓。

下面定义几个主要方法,包含识别文本是否在文本框里,识别文本的背景颜色、计算坐标等。

judge_side 用于根据图像中边界框的位置和颜色信息来判断文本所在的位置是在左侧、右侧还是无法判断。以下是对代码的逐步解释:

def judge_side(img, bbox, rectangles, detectedtext):"""Judge the left/right side based on the occurrence of white/green pixels."""x_min, x_max, y_min, y_max = get_bbox_bounds(bbox)  # 获取边界框的最小和最大坐标值side = None# 遍历矩形区域列表for rect in rectangles:# 判断边界框是否在矩形区域内(考虑了一定的容错范围)if (rect[0][0] - 50 <= x_min <= rect[1][0] + 50 andrect[0][1] - 50 <= y_min <= rect[1][1] + 50 andrect[0][0] - 50 <= x_max <= rect[1][0] + 50 andrect[0][1] - 50 <= y_max <= rect[1][1] + 50):side = rect  # 如果在矩形区域内,则将该矩形区域赋值给 side# 如果 side 存在或者检测到的文本长度大于等于3if side or (detectedtext and len(detectedtext) >= 3):# 调用 get_color 方法,获取图像区域的颜色side = get_color(img[x_min - 60:x_max + 60, y_min - 60:y_max + 60])return side  # 返回判断结果def get_bbox_bounds(bbox):x_min = min([x['X'] for x in bbox])x_max = max([x['X'] for x in bbox])y_min = min([x['Y'] for x in bbox])y_max = max([x['Y'] for x in bbox])return x_min, x_max, y_min, y_max

get_color 该函数接受一个图像 img 作为输入,然后根据颜色的平均值(色相、饱和度、亮度)来判断图像的颜色,并返回相应的结果。

def get_color(img):if img.shape[0] == 0 or img.shape[1] == 0:return "UNK"  # 如果图像高度或宽度为0,返回未知颜色# 颜色提取hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # 将图像颜色空间转换为HSV,便于颜色分离average_hue = np.median(hsv[:,:,0])  # 色相的中位数average_saturation = np.median(hsv[:,:,1])  # 饱和度的中位数average_value = np.median(hsv[:,:,2])   # 亮度的中位数print('RBG--hsv:', average_hue, average_saturation, average_value)# 定义颜色范围green_min = [35, 43, 46]green_max = [77, 255, 255]back_min = [0, 0, 40]back_max = [180, 43, 220]white_min = [0, 0, 239]white_max = [180, 30, 255]# 根据颜色范围判断颜色if (average_hue >= green_min[0] and average_hue <= green_max[0] andaverage_saturation >= green_min[1] and average_saturation <= green_max[1] andaverage_value >= green_min[2] and average_value <= green_max[2]):print("color is green")return 'RIGHT'elif (average_hue >= white_min[0] and average_hue <= white_max[0] andaverage_saturation >= white_min[1] and average_saturation <= white_max[1] andaverage_value >= white_min[2] and average_value <= white_max[2]):print("color is white")return "LEFT"elif (average_hue >= back_min[0] and average_hue <= back_max[0] andaverage_saturation >= back_min[1] and average_saturation <= back_max[1] andaverage_value >= back_min[2] and average_value <= back_max[2]):print("color is gray")return "LEFT"else:print("not white and green", average_hue, average_saturation, average_value)return "UNK"  # 如果不在上述颜色范围内,返回未知颜色

这个函数通过计算颜色的中位数来判断图像的整体颜色,然后根据预定义的颜色范围,判断图像是绿色、白色、灰色还是未知颜色,并返回相应的标签。函数中的颜色范围是通过调试和实验得到的,可以根据实际情况进行调整。

主代码入口:

with open(jsn_fpath, 'r', encoding='UTF-8') as i_file:jsn_data = json.load(i_file)
with open(pdf_path, 'rb') as i_file:pix = i_file.read()
conv_list = []
regex = re.compile(r'[0-9]+:[0-9]+$|中国移动|输入聊天') 
print(len(jsn_data['TextDetections']), '-------------------')
for hits in jsn_data['TextDetections']:pix = next(gen)pix = np.frombuffer(pix, np.uint8)img = cv2.imdecode(pix, cv2.IMREAD_COLOR)rectangles  = get_contours(img)for hit in hits:y_list = [y for y in hit.get('Polygon')]  #获取句子y轴坐标text = hit["DetectedText"]#根据y轴坐标,使用极差计算句子高度:如果句子水平方向,高度在一个字的高度左右,如果是水印则会异常高ptp = np.ptp(np.array([i.get('Y') for i in y_list]))  #过滤异常高度、异常字体大小和时间文本if hit['Confidence'] <= CONF_THRES or ptp > ptp_max or ptp <= ptp_min or re.search(regex, text):  print("pass -----")continueprint("text:",text)side = judge_side(img, hit['Polygon'], rectangles,hit["DetectedText"])if side == 'UNK' or not side:# print("side:", hit["DetectedText"])continueelse:conv_list.append(f'{side}: {text}')

这段代码通过循环遍历腾讯云OCR返回的每一条文本信息。在处理每一条文本信息时,会进行一系列的过滤操作,包括置信度、文本框高度、异常文本等。最终,将符合条件的文本按照其位置('左'、'右')以及文本内容添加到 conv_list 列表中。这个列表最终用于存储经过筛选后的文本信息,供后续处理和分析。

上述代码完成了基本的聊天图片的文本识别步骤,但要实现自动化识别大量聊天图片还需进一步完善。比如这里使用了jpg图片进行识别,如果使用多个分页的pdf又如何识别呢。

下面将完整自动化识别大量聊天图片的脚本写好了,欢迎感兴趣的小伙伴收看我的专栏博客:

完整代码:

https://blog.csdn.net/qq_20163065/article/details/135052800?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135052800%22%2C%22source%22%3A%22qq_20163065%22%7D

对于更多ai语料,欢迎感兴趣的朋友私聊我。

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

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

相关文章

基于Springboot的任务发布平台设计与实现(源码齐全+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

深度学习笔记_6经典预训练网络LeNet-18解决FashionMNIST数据集

1、 调用模型库&#xff0c;定义参数&#xff0c;做数据预处理 import numpy as np import torch from torchvision.datasets import FashionMNIST import torchvision.transforms as transforms from torch.utils.data import DataLoader import torch.nn.functional as F im…

Vue学习笔记-Vue3中的customRef

作用 创建一个自定义的ref&#xff0c;并对其依赖项的更新和触发进行显式控制 案例 描述&#xff1a;向输入框中输入内容&#xff0c;在下方延迟1秒展示输入内容 代码&#xff1a; <template><input type"text" v-model"keyword"><h3&…

关于“Python”的核心知识点整理大全24

目录 ​编辑 10.1.6 包含一百万位的大型文件 pi_string.py 10.1.7 圆周率值中包含你的生日吗 10.2 写入文件 10.2.1 写入空文件 write_message.py programming.txt 10.2.2 写入多行 10.2.3 附加到文件 write_message.py programming.txt 10.3 异常 10.3.1 处理 Ze…

数据科学知识库

​ 我的博客是一个技术分享平台&#xff0c;涵盖了机器学习、数据可视化、大数据分析、数学统计学、推荐算法、Linux命令及环境搭建&#xff0c;以及Kafka、Flask、FastAPI、Docker等组件的使用教程。 在这个信息时代&#xff0c;数据已经成为了一种新的资源&#xff0c;而机…

环境搭建及源码运行_java环境搭建_mysql安装

书到用时方恨少、觉知此时要躬行&#xff1b;拥有技术&#xff0c;成就未来&#xff0c;抖音视频教学地址&#xff1a;​​​​​​​​​​​​​​ 1、介绍 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle旗下产品。MySQL是最…

go原生http开发简易blog(一)项目简介与搭建

文章目录 一、项目简介二、项目搭建前置知识三、首页- - -前端文件与后端结构体定义四、配置文件加载五、构造假数据- - -显示首页内容 代码地址&#xff1a;https://gitee.com/lymgoforIT/goblog 一、项目简介 使用Go原生http开发一个简易的博客系统&#xff0c;包含一下功能…

UE5:Lumen 框架

1.Lumen渲染流程框架 2.Lumen基本概念 2.1 LumenCard & LumenMeshCards LumenMeshCards&#xff1a;一组带有方向性的模型简化代理&#xff0c;视模型复杂度不同可能包含6个及以上数量的LumenCard&#xff1b;用来提供光照采样的位置和方向。 2.2 LumenCardPage & Lu…

Pycharm 如何更改成中文版| Python循环语句| for 和 else 的搭配使用

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

【Linux】在vim中批量注释与批量取消注释

在vim编辑器中&#xff0c;批量注释和取消注释的操作可以通过进入V-BLOCK模式、选择要注释或取消注释的内容、输入注释符号或选中已有的注释符号和按键完成。这些操作可以大大提高代码或文本的编写和修改效率&#xff0c;是vim编辑器中常用的操作之一。 1.在vim中批量注释的步…

常用网安渗透工具及命令(扫目录、解密爆破、漏洞信息搜索)

目录 dirsearch&#xff1a; dirmap&#xff1a; 输入目标 文件读取 ciphey&#xff08;很强的一个自动解密工具&#xff09;&#xff1a; john(破解密码)&#xff1a; whatweb指纹识别&#xff1a; searchsploit&#xff1a; 例1&#xff1a; 例2&#xff1a; 例3&…

<JavaEE> 网络编程 -- 网络通信基础(协议和协议分层、数据封装和分用)

目录 一、IP地址 1&#xff09;IP地址的概念 2&#xff09;IP地址的格式 二、端口号 1&#xff09;端口号的概念 2&#xff09;端口号的格式 3&#xff09;什么是知名端口号&#xff1f; 三、协议 1&#xff09;协议的概念 2&#xff09;协议的作用 3&#xff09;TC…

【idea】解决sprintboot项目创建遇到的问题

目录 一、报错Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found 二、报错java: 错误: 无效的源发行版&#xff1a;17 三、java: 无法访问org.springframework.web.bind.annotation.CrossOrigin 四、整合mybatis的时候&#xff0c;报java.lang.Ill…

人工智能中的核心概念

1 概述 人工智能英文缩写为AI&#xff0c;是一种由人制造出来的机器&#xff0c;该机器可以模仿人的思想和行为&#xff0c;从而体现出一种智能的反应。 人工智能的产业链分为基础层、技术层、应用层三个层次。 基础层包括&#xff1a;芯片、大数据、算法系统、网络等多项基础…

基于Tkinter和OpenCV的目标检测程序源码+权重文件,实现摄像头和视频文件的实时目标检测采用YOLOv8模型进行目标检测

基于Tkinter和OpenCV的目标检测程序源码权重文件&#xff0c;实现摄像头和视频文件的实时目标检测采用YOLOv8模型进行目标检测 项目描述 本项目是一个基于Tkinter和OpenCV的目标检测应用程序&#xff0c;实现了摄像头和视频文件的实时目标检测。通过YOLOv8模型进行目标检测&a…

ShuffleNet V1+V2(pytorch)

V1 V1根本思想&#xff1a; 1.GConv替换resnet的普通1*1Conv 2.GConv后加channel shuffle模块 对GConv的不同组进行重新组合。channel_shuffle a是resnet模块&#xff0c;b&#xff0c;c是ShuffleNetV1的block&#xff0c;在V1版中&#xff0c;两模块branch2的第一个1*1卷积…

JavaScript 事件冒泡与捕获机制 --- 带动态图理解

&#xff08;1&#xff09;.事件捕获 从根元素往上传递 --- ---&#xff08;由外到内&#xff09; &#xff08;2&#xff09;.事件冒泡 从元素传递到它的根源素 --- --- &#xff08;由内到外&#xff09; 代码&#xff1a; <!DOCTYPE html> <html lang"en&q…

在 Windows 11/10 上恢复已删除文本文件的 4 种方法

您是否不小心从桌面上删除了文本文件&#xff1f;不用担心。您可以在 Windows 上恢复已删除的文本文件&#xff01; 对于那些有大量工作要做的人来说&#xff0c;便利贴无疑是一种福音。便利贴能够立即记下任何内容并使其可见&#xff0c;而不会占用太多屏幕空间&#xff0c;因…

vue写了这么久了您是否知道:为什么data属性是一个函数而不是一个对象?

一、实例和组件定义data的区别 vue实例的时候定义data属性既可以是一个对象&#xff0c;也可以是一个函数 const app new Vue({el:"#app",// 对象格式data:{foo:"foo"},// 函数格式data(){return {foo:"foo"}} })组件中定义data属性&#xff…

Vue 项目关于在生产环境下调试

前言 开发项目时&#xff0c;在本地调试没问题&#xff0c;但是部署到生产会遇到一些很奇怪的问题&#xff0c;本地又没法调&#xff0c;就需要在生产环境/域名下进行调试。 在这里介绍一个插件Vue force dev ,浏览器扩展里下载 即便是设置了Vue.config.devtoolsfalse 只要安…