Python教程(四十二):计算机视觉-图像处理和分析
itomcoil 2025-08-01 17:47 2 浏览
今日目标
o 理解计算机视觉的基本概念和应用
o 掌握OpenCV图像处理基础操作
o 学会图像滤波、边缘检测和特征提取
o 了解图像分割和目标检测技术
o 掌握深度学习在计算机视觉中的应用
计算机视觉概述
计算机视觉是人工智能的重要分支,致力于让计算机理解和处理视觉信息:
o 图像处理:滤波、变换、增强
o 特征提取:边缘、角点、纹理特征
o 目标检测:定位、识别、跟踪
o 图像理解:场景理解、语义分割
计算机视觉应用领域
# 主要应用领域:
# - 自动驾驶和机器人视觉
# - 医疗影像诊断
# - 安防监控和人脸识别
# - 工业质量检测
# - 增强现实和虚拟现实
# - 图像搜索和推荐
OpenCV基础
1. 安装和导入
pip install opencv-python opencv-contrib-python matplotlib numpy scikit-image pillow
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import skimage
from skimage import filters, feature, segmentation
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
print(f"OpenCV版本: {cv2.__version__}")
print(f"NumPy版本: {np.__version__}")
2. 图像读取和显示
def image_basic_operations():
"""图像基本操作示例"""
# 创建示例图像
def create_sample_image():
"""创建示例图像"""
# 创建一个彩色图像
img = np.zeros((300, 400, 3), dtype=np.uint8)
# 绘制矩形
cv2.rectangle(img, (50, 50), (150, 150), (255, 0, 0), -1) # 蓝色矩形
cv2.rectangle(img, (200, 50), (300, 150), (0, 255, 0), -1) # 绿色矩形
# 绘制圆形
cv2.circle(img, (100, 250), 50, (0, 0, 255), -1) # 红色圆形
# 添加文字
cv2.putText(img, 'OpenCV', (150, 280), cv2.FONT_HERSHEY_SIMPLEX,
1, (255, 255, 255), 2)
return img
# 创建示例图像
sample_img = create_sample_image()
print("=== 图像基本操作 ===")
# 1. 图像信息
print(f"图像形状: {sample_img.shape}")
print(f"图像类型: {sample_img.dtype}")
print(f"图像大小: {sample_img.size} 像素")
# 2. 图像显示
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.imshow(cv2.cvtColor(sample_img, cv2.COLOR_BGR2RGB))
plt.title('原始图像')
plt.axis('off')
# 3. 颜色空间转换
gray_img = cv2.cvtColor(sample_img, cv2.COLOR_BGR2GRAY)
hsv_img = cv2.cvtColor(sample_img, cv2.COLOR_BGR2HSV)
plt.subplot(1, 3, 2)
plt.imshow(gray_img, cmap='gray')
plt.title('灰度图像')
plt.axis('off')
plt.subplot(1, 3, 3)
plt.imshow(cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB))
plt.title('HSV图像')
plt.axis('off')
plt.tight_layout()
plt.show()
# 4. 图像保存
cv2.imwrite('sample_image.jpg', sample_img)
print("图像已保存为 sample_image.jpg")
return sample_img, gray_img, hsv_img
# 运行图像基本操作示例
sample_image, gray_image, hsv_image = image_basic_operations()
3. 图像变换
def image_transformations():
"""图像变换示例"""
# 使用之前的示例图像
img = sample_image
print("=== 图像变换 ===")
# 1. 图像缩放
height, width = img.shape[:2]
resized_img = cv2.resize(img, (width//2, height//2))
enlarged_img = cv2.resize(img, (width*2, height*2))
# 2. 图像旋转
center = (width//2, height//2)
rotation_matrix = cv2.getRotationMatrix2D(center, 45, 1.0)
rotated_img = cv2.warpAffine(img, rotation_matrix, (width, height))
# 3. 图像翻转
flipped_horizontal = cv2.flip(img, 1) # 水平翻转
flipped_vertical = cv2.flip(img, 0) # 垂直翻转
# 4. 图像平移
translation_matrix = np.float32([[1, 0, 50], [0, 1, 30]])
translated_img = cv2.warpAffine(img, translation_matrix, (width, height))
# 可视化变换结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title('原始图像')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(cv2.cvtColor(resized_img, cv2.COLOR_BGR2RGB))
plt.title('缩放图像')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(cv2.cvtColor(rotated_img, cv2.COLOR_BGR2RGB))
plt.title('旋转图像')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(cv2.cvtColor(flipped_horizontal, cv2.COLOR_BGR2RGB))
plt.title('水平翻转')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(cv2.cvtColor(flipped_vertical, cv2.COLOR_BGR2RGB))
plt.title('垂直翻转')
plt.axis('off')
plt.subplot(2, 3, 6)
plt.imshow(cv2.cvtColor(translated_img, cv2.COLOR_BGR2RGB))
plt.title('平移图像')
plt.axis('off')
plt.tight_layout()
plt.show()
return {
'resized': resized_img,
'rotated': rotated_img,
'flipped_h': flipped_horizontal,
'flipped_v': flipped_vertical,
'translated': translated_img
}
# 运行图像变换示例
transform_results = image_transformations()
图像滤波和增强
1. 空间域滤波
def spatial_filtering():
"""空间域滤波示例"""
# 创建带噪声的图像
def create_noisy_image():
"""创建带噪声的图像"""
img = np.zeros((200, 200), dtype=np.uint8)
# 绘制几何图形
cv2.rectangle(img, (50, 50), (150, 150), 255, -1)
cv2.circle(img, (100, 100), 30, 0, -1)
# 添加高斯噪声
noise = np.random.normal(0, 25, img.shape).astype(np.uint8)
noisy_img = cv2.add(img, noise)
return img, noisy_img
original_img, noisy_img = create_noisy_image()
print("=== 空间域滤波 ===")
# 1. 均值滤波
mean_filtered = cv2.blur(noisy_img, (5, 5))
# 2. 高斯滤波
gaussian_filtered = cv2.GaussianBlur(noisy_img, (5, 5), 0)
# 3. 中值滤波
median_filtered = cv2.medianBlur(noisy_img, 5)
# 4. 双边滤波
bilateral_filtered = cv2.bilateralFilter(noisy_img, 9, 75, 75)
# 可视化滤波结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(original_img, cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(noisy_img, cmap='gray')
plt.title('带噪声图像')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(mean_filtered, cmap='gray')
plt.title('均值滤波')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(gaussian_filtered, cmap='gray')
plt.title('高斯滤波')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(median_filtered, cmap='gray')
plt.title('中值滤波')
plt.axis('off')
plt.subplot(2, 3, 6)
plt.imshow(bilateral_filtered, cmap='gray')
plt.title('双边滤波')
plt.axis('off')
plt.tight_layout()
plt.show()
return {
'original': original_img,
'noisy': noisy_img,
'mean_filtered': mean_filtered,
'gaussian_filtered': gaussian_filtered,
'median_filtered': median_filtered,
'bilateral_filtered': bilateral_filtered
}
# 运行空间域滤波示例
filtering_results = spatial_filtering()
2. 边缘检测
def edge_detection():
"""边缘检测示例"""
# 使用之前的示例图像
img = sample_image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print("=== 边缘检测 ===")
# 1. Sobel算子
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
sobel_combined = np.sqrt(sobel_x**2 + sobel_y**2)
sobel_combined = np.uint8(sobel_combined)
# 2. Canny边缘检测
canny_edges = cv2.Canny(gray, 50, 150)
# 3. Laplacian算子
laplacian = cv2.Laplacian(gray, cv2.CV_64F)
laplacian = np.uint8(np.absolute(laplacian))
# 4. 使用skimage的Canny
skimage_canny = feature.canny(gray, sigma=1)
# 可视化边缘检测结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(gray, cmap='gray')
plt.title('灰度图像')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(sobel_x, cmap='gray')
plt.title('Sobel X方向')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(sobel_y, cmap='gray')
plt.title('Sobel Y方向')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(sobel_combined, cmap='gray')
plt.title('Sobel组合')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(canny_edges, cmap='gray')
plt.title('Canny边缘检测')
plt.axis('off')
plt.subplot(2, 3, 6)
plt.imshow(laplacian, cmap='gray')
plt.title('Laplacian算子')
plt.axis('off')
plt.tight_layout()
plt.show()
return {
'sobel_x': sobel_x,
'sobel_y': sobel_y,
'sobel_combined': sobel_combined,
'canny': canny_edges,
'laplacian': laplacian,
'skimage_canny': skimage_canny
}
# 运行边缘检测示例
edge_results = edge_detection()
特征提取
1. 角点检测
def corner_detection():
"""角点检测示例"""
# 创建测试图像
def create_corner_test_image():
"""创建角点测试图像"""
img = np.zeros((300, 300), dtype=np.uint8)
# 绘制矩形
cv2.rectangle(img, (50, 50), (150, 150), 255, 2)
# 绘制三角形
pts = np.array([[200, 50], [250, 150], [150, 150]], np.int32)
cv2.polylines(img, [pts], True, 255, 2)
# 绘制圆形
cv2.circle(img, (100, 250), 50, 255, 2)
return img
test_img = create_corner_test_image()
print("=== 角点检测 ===")
# 1. Harris角点检测
harris_corners = cv2.cornerHarris(test_img, blockSize=2, ksize=3, k=0.04)
harris_corners = cv2.dilate(harris_corners, None)
# 2. Shi-Tomasi角点检测
shi_tomasi_corners = cv2.goodFeaturesToTrack(test_img, maxCorners=25,
qualityLevel=0.01, minDistance=10)
# 3. FAST角点检测
fast = cv2.FastFeatureDetector_create()
fast_keypoints = fast.detect(test_img, None)
# 可视化角点检测结果
plt.figure(figsize=(15, 5))
# Harris角点
plt.subplot(1, 3, 1)
plt.imshow(test_img, cmap='gray')
plt.imshow(harris_corners, cmap='jet', alpha=0.5)
plt.title('Harris角点检测')
plt.axis('off')
# Shi-Tomasi角点
plt.subplot(1, 3, 2)
plt.imshow(test_img, cmap='gray')
if shi_tomasi_corners is not None:
for corner in shi_tomasi_corners:
x, y = corner.ravel()
plt.plot(x, y, 'ro', markersize=5)
plt.title('Shi-Tomasi角点检测')
plt.axis('off')
# FAST角点
plt.subplot(1, 3, 3)
plt.imshow(test_img, cmap='gray')
for kp in fast_keypoints:
x, y = kp.pt
plt.plot(x, y, 'go', markersize=5)
plt.title('FAST角点检测')
plt.axis('off')
plt.tight_layout()
plt.show()
return {
'harris': harris_corners,
'shi_tomasi': shi_tomasi_corners,
'fast': fast_keypoints
}
# 运行角点检测示例
corner_results = corner_detection()
2. 特征匹配
def feature_matching():
"""特征匹配示例"""
# 创建两个相似但略有不同的图像
def create_test_images():
"""创建测试图像"""
img1 = np.zeros((200, 200), dtype=np.uint8)
img2 = np.zeros((200, 200), dtype=np.uint8)
# 在第一个图像中绘制图案
cv2.rectangle(img1, (50, 50), (150, 150), 255, -1)
cv2.circle(img1, (100, 100), 30, 0, -1)
# 在第二个图像中绘制相同的图案,但位置略有偏移
cv2.rectangle(img2, (60, 60), (160, 160), 255, -1)
cv2.circle(img2, (110, 110), 30, 0, -1)
return img1, img2
img1, img2 = create_test_images()
print("=== 特征匹配 ===")
# 1. SIFT特征检测
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# 2. 特征匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
# 3. 应用比率测试
good_matches = []
for match_pair in matches:
if len(match_pair) == 2:
m, n = match_pair
if m.distance < 0.75 * n.distance:
good_matches.append(m)
# 4. 绘制匹配结果
matched_img = cv2.drawMatches(img1, kp1, img2, kp2, good_matches, None,
flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
# 可视化结果
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.imshow(img1, cmap='gray')
plt.title('图像1')
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(img2, cmap='gray')
plt.title('图像2')
plt.axis('off')
plt.subplot(1, 3, 3)
plt.imshow(cv2.cvtColor(matched_img, cv2.COLOR_BGR2RGB))
plt.title('特征匹配结果')
plt.axis('off')
plt.tight_layout()
plt.show()
print(f"检测到的特征点数量: 图像1={len(kp1)}, 图像2={len(kp2)}")
print(f"匹配的特征点数量: {len(good_matches)}")
return {
'keypoints1': kp1,
'keypoints2': kp2,
'descriptors1': des1,
'descriptors2': des2,
'matches': good_matches,
'matched_image': matched_img
}
# 运行特征匹配示例
matching_results = feature_matching()
图像分割
1. 阈值分割
def image_segmentation():
"""图像分割示例"""
# 创建测试图像
def create_segmentation_test_image():
"""创建分割测试图像"""
img = np.zeros((200, 200), dtype=np.uint8)
# 添加不同灰度值的区域
img[50:100, 50:100] = 100 # 中等灰度
img[120:170, 120:170] = 200 # 高灰度
img[50:100, 120:170] = 50 # 低灰度
# 添加噪声
noise = np.random.normal(0, 10, img.shape).astype(np.uint8)
img = cv2.add(img, noise)
return img
test_img = create_segmentation_test_image()
print("=== 图像分割 ===")
# 1. 全局阈值分割
_, global_thresh = cv2.threshold(test_img, 127, 255, cv2.THRESH_BINARY)
# 2. 自适应阈值分割
adaptive_thresh = cv2.adaptiveThreshold(test_img, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
# 3. Otsu阈值分割
_, otsu_thresh = cv2.threshold(test_img, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 4. 多阈值分割
_, thresh1 = cv2.threshold(test_img, 75, 255, cv2.THRESH_BINARY)
_, thresh2 = cv2.threshold(test_img, 150, 255, cv2.THRESH_BINARY)
multi_thresh = thresh1 + thresh2
# 可视化分割结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(test_img, cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(global_thresh, cmap='gray')
plt.title('全局阈值分割')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(adaptive_thresh, cmap='gray')
plt.title('自适应阈值分割')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(otsu_thresh, cmap='gray')
plt.title('Otsu阈值分割')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(multi_thresh, cmap='gray')
plt.title('多阈值分割')
plt.axis('off')
# 直方图
plt.subplot(2, 3, 6)
plt.hist(test_img.ravel(), bins=256, range=[0, 256])
plt.title('图像直方图')
plt.xlabel('像素值')
plt.ylabel('频次')
plt.tight_layout()
plt.show()
return {
'global_thresh': global_thresh,
'adaptive_thresh': adaptive_thresh,
'otsu_thresh': otsu_thresh,
'multi_thresh': multi_thresh
}
# 运行图像分割示例
segmentation_results = image_segmentation()
2. 分水岭分割
def watershed_segmentation():
"""分水岭分割示例"""
# 创建测试图像
def create_watershed_test_image():
"""创建分水岭测试图像"""
img = np.zeros((200, 200), dtype=np.uint8)
# 绘制几个圆形区域
cv2.circle(img, (50, 50), 30, 255, -1)
cv2.circle(img, (150, 50), 25, 255, -1)
cv2.circle(img, (100, 150), 35, 255, -1)
# 添加噪声
noise = np.random.normal(0, 20, img.shape).astype(np.uint8)
img = cv2.add(img, noise)
return img
test_img = create_watershed_test_image()
print("=== 分水岭分割 ===")
# 1. 图像预处理
# 高斯滤波去噪
blurred = cv2.GaussianBlur(test_img, (5, 5), 0)
# 阈值分割
_, thresh = cv2.threshold(blurred, 127, 255, cv2.THRESH_BINARY)
# 形态学操作
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
# 确定背景区域
sure_bg = cv2.dilate(opening, kernel, iterations=3)
# 确定前景区域
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
# 找到未知区域
unknown = cv2.subtract(sure_bg, sure_fg)
# 2. 标记
_, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
markers[unknown == 255] = 0
# 3. 应用分水岭算法
markers = cv2.watershed(cv2.cvtColor(test_img, cv2.COLOR_GRAY2BGR), markers)
# 可视化结果
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.imshow(test_img, cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(2, 3, 2)
plt.imshow(thresh, cmap='gray')
plt.title('阈值分割')
plt.axis('off')
plt.subplot(2, 3, 3)
plt.imshow(sure_bg, cmap='gray')
plt.title('确定背景')
plt.axis('off')
plt.subplot(2, 3, 4)
plt.imshow(sure_fg, cmap='gray')
plt.title('确定前景')
plt.axis('off')
plt.subplot(2, 3, 5)
plt.imshow(unknown, cmap='gray')
plt.title('未知区域')
plt.axis('off')
plt.subplot(2, 3, 6)
plt.imshow(markers, cmap='jet')
plt.title('分水岭分割结果')
plt.axis('off')
plt.tight_layout()
plt.show()
return {
'sure_bg': sure_bg,
'sure_fg': sure_fg,
'unknown': unknown,
'markers': markers
}
# 运行分水岭分割示例
watershed_results = watershed_segmentation()
今日总结
今天我们学习了计算机视觉的基础知识:
1. OpenCV基础:图像读取、显示、基本操作
2. 图像变换:缩放、旋转、翻转、平移
3. 图像滤波:均值、高斯、中值、双边滤波
4. 边缘检测:Sobel、Canny、Laplacian算子
5. 特征提取:角点检测、特征匹配
6. 图像分割:阈值分割、分水岭算法
计算机视觉是AI的重要分支,掌握这些技术可以构建智能图像处理系统。
相关推荐
- C|经典实例理解算法之顺推、逆推、迭代、递归思想
-
递推算法可以不断利用已有的信息推导(迭代)出新的信息,在日常应用中有如下两种递推算法。①顺推法:从已知条件出发,逐步推算出要解决问题的方法。例如斐波那契数列就可以通过顺推法不断递推算出新的数据。②...
- [西门子PLC] 博途编程之递归算法
-
首先跟大伙讲一讲哈,递归算法瞅着是挺优雅挺不错的,可实际上没啥大用,在真正的项目里能不用就别用递归,为啥呢?因为用了递归可能会惹出大麻烦,后面会给大伙举例讲讲原因。那啥叫递归呢?从名字上就能看出来,就...
- SQL 也能递归?一文搞懂 Recursive CTE的魔力
-
很多人以为递归(Recursive)只属于编程语言,和SQL没什么关系。但其实SQL中也能实现递归操作,特别是在处理树结构、路径查找时,WITHRECURSIVE展现出强大威力。本文将带你...
- 10张动图学会python循环与递归
-
一图胜千言! 循环难学?十张动图GIFS有助于认识循环、递归、二分检索等概念的具体运行情况。 本文代码实例以Python语言编写。 一、循环 GIF1:最简单的while循环 GIF...
- C语言学习之-----(十三) 函数递归
-
(十三)函数递归一、栈在说函数递归的时候,顺便说一下栈的概念。栈是一个后进先出的压入(push)和弹出(pop)式数据结构。在程序运行时,系统每次向栈中压入一个对象,然后栈指针向下移动一个位置。当系...
- Python自动化办公应用学习笔记19—— 循环控制:break 和 continue
-
在Python的循环结构中,break和continue是两个特殊的保留字,主要用于改变循环的执行流程。1.定义与核心作用break:立即终止当前循环,跳出整个循环体(仅限最内层循环)conti...
-
- 循环与递归的那些事
-
大家好,我是贠学文,点击右上方“关注”,每天为您分享java程序员需要掌握的知识点干货。在任何的编程语言中,循环和递归永远都是一个避不开的话题,因为在某些特定的场景下,用递归确实要比循环简单得多,比如说遍历文件夹目录等等,但是,递归也有下面...
-
2025-08-02 18:49 itomcoil
- 漫谈递归、迭代、循环——人理解迭代,神理解递归
-
后续计划好几天没有更新了,没有偷懒。随着源码的阅读,学习到了字典和集合的底层实现。字典这种数据结构的搜索效率很高,底层结构采用了效率优于红黑树的哈希表。红黑树是一种平衡二叉树,C++中的map和lin...
- Excel递归与循环——货物分箱问题
-
递归指通过函数自身调用实现复杂计算,在Excel中多通过支持递归的函数(如LAMBDA)实现。第一,简化复杂逻辑表达:对于有明确递推关系的问题,递归能将多层嵌套的逻辑转化为简洁的自我调用形式,比手...
- MongoDB入门之索引
-
索引就像书的目录,如果查找某内容在没有目录的帮助下,只能全篇查找翻阅,这导致效率非常的低下;如果在借助目录情况下,就能很快的定位具体内容所在区域,效率会直线提高。索引简介首先打开命令行,输入mongo...
- MongoDB之集合管理一
-
最近的几篇博客都是关于MongoDB的,虽然个人感觉也没多少知识点,但没想到竟然有转载我的博客的,不管有经过我同意还是没经过我同意,说明写的应该还是有价值的,这也是我写博客的一个动力之一吧。上一博客学...
- SpringBoot集成扩展-访问NoSQL数据库之Redis和MongoDB!
-
与关系型数据库一样,SpringBoot也提供了对NoSQL数据库的集成扩展,如对Redis和MongoDB等数据库的操作。通过默认配置即可使用RedisTemplate和MongoTemplate...
- 揭秘你不会画“信息结构图”的本质
-
编辑导语:产品信息结构图有助于清晰地展示产品信息,一定程度上可以为后台上传数据提供依据,但不少人可能觉得产品信息结构图很难,这可能是对数据库表结构不理解等因素导致的。本篇文章里,作者就产品信息结构图的...
- MongoDB导入导出备份数据
-
要提前安装mongodb-database-tools参考:centos离线安装mongodb-database-tools导出数据常用的导出有两种:mongodump和mongoexport,两种方...
- mongodb导入导出及备份
-
-------------------MongoDB数据导入与导出-------------------1、导出工具:mongoexport1、概念:mongoDB中的mongoexport...
- 一周热门
- 最近发表
- 标签列表
-
- ps图案在哪里 (33)
- super().__init__ (33)
- python 获取日期 (34)
- 0xa (36)
- super().__init__()详解 (33)
- python安装包在哪里找 (33)
- linux查看python版本信息 (35)
- python怎么改成中文 (35)
- php文件怎么在浏览器运行 (33)
- eval在python中的意思 (33)
- python安装opencv库 (35)
- python div (34)
- sticky css (33)
- python中random.randint()函数 (34)
- python去掉字符串中的指定字符 (33)
- python入门经典100题 (34)
- anaconda安装路径 (34)
- yield和return的区别 (33)
- 1到10的阶乘之和是多少 (35)
- python安装sklearn库 (33)
- dom和bom区别 (33)
- js 替换指定位置的字符 (33)
- python判断元素是否存在 (33)
- sorted key (33)
- shutil.copy() (33)