深度学习中基于python的预处理和图像扩增方法

这篇具有很好参考价值的文章主要介绍了深度学习中基于python的预处理和图像扩增方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

容易出现的报错:

cv2.error: OpenCV(4.7.0) D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:692: error: (-2:Unspecified error) could not find a writer for the specified extension in function 'cv::imwrite_'

错误原因通常为保存的路径不正确:

cv2.imwrite('./crop_images/origin_imgs', roi)

应改为:

cv2.imwrite(os.path.join('./crop_images/origin_imgs', img_name), roi)

即第一个参数应该写到文件的名称,而不能只写到文件夹就停止。

判断图片是否为灰度图片

灰度图片和黑白图片有些相似,但并不完全相同。

灰度图片是指每个像素点的颜色由灰度值来表示,通常使用8位无符号整数(0-255)表示。灰度图像中的每个像素点可能具有不同的灰度值,因此图像中可能会有许多不同的灰度级别。

黑白图片通常指的是二值图像,其中只有两种像素值,通常是黑色和白色。黑白图像中的每个像素点只有两种可能的取值,因此图像中只有两个灰度级别。

虽然灰度图像和黑白图像都只是使用灰度值来表示图像中的像素点,但它们在像素的取值范围和数量上有所不同。

# 黑白照片(灰度图)识别
def isGrayMap(img, threshold = 15):
    """
    入参:
    img:PIL读入的图像
    threshold:判断阈值,图片3个通道间差的方差均值小于阈值则判断为灰度图。
    阈值设置的越小,容忍出现彩色面积越小;设置的越大,那么就可以容忍出现一定面积的彩色,例如微博截图。
    如果阈值设置的过小,某些灰度图片会被漏检,这是因为某些黑白照片存在偏色,例如发黄的黑白老照片、
    噪声干扰导致灰度图不同通道间值出现偏差(理论上真正的灰度图是RGB三个通道的值完全相等或者只有一个通道,
    然而实际上各通道间像素值略微有偏差看起来仍是灰度图)
    出参:
    bool值
    """
    if len(img.getbands()) == 1:
        return True
    img1 = np.asarray(img.getchannel(channel=0), dtype=np.int16)
    img2 = np.asarray(img.getchannel(channel=1), dtype=np.int16)
    img3 = np.asarray(img.getchannel(channel=2), dtype=np.int16)
    diff1 = (img1 - img2).var()
    diff2 = (img2 - img3).var()
    diff3 = (img3 - img1).var()
    diff_sum = (diff1 + diff2 + diff3) / 3.0
    if diff_sum <= threshold:
        return True
    else:
        return False

参考

批量给图片文件重命名

给一批文件重命名

问题1:使用os.path.join()函数合并路径的时候,只显示后面的。
原因:使用os.path.join(r’D:\datasets\new_name’, “/1000” + str(i) + “.jpg”)

os.path.join()函数中可以传入多个路径: 会从第一个以”/”开头的参数开始拼接,之前的参数全部丢弃。
以上一种情况为先。在上一种情况确保情况下,若出现”./”开头的参数,会从”./”开头的参数的上一个参数开始拼接

注意下面代码中的os.rename(old_name, new_name)是对原始文件直接操作,会导致原始文件消失,如果要保留原始文件,使用shutil.copy(old_name, new_name)。

# 日期:  2023/4/22 11:47
import os

root_path = r'D:\datasets\1osr_original_img'

if os.path.exists(root_path):
    i = 1
    for filename in os.listdir(root_path):
        # 把图像改名
        old_name = os.path.join(root_path, filename)
        # 保证图片文件名称位数一致
        lens = 5 - len(str(i))
        new_name = os.path.join(root_path, "1" + "0"*lens + str(i) + ".jpg")  # 100001
        # 当文件不存在的时候创建,否则会报错:当文件已存在时,无法创建该文件。
        if not os.path.exists(new_name):
            os.rename(old_name, new_name)
        i += 1

        # 记录修改过程
        filelist = []
        if old_name != new_name:
            filelist.append('Old: ' + old_name)
            filelist.append('New: ' + new_name)

            f = open("rename_log.txt", "a")
            for file in filelist:
                f.write(file + '\n')

            f.close()
    print('OK')
else:
    print("路径不存在!")


注意:使用该代码处理文件会删除原来的图片,只保存新的图片。
操作有风险,所以可以记录修改过程。

参考

把一批文件顺序打乱重命名

# 日期:  2023/4/22 11:47
import os
import random

root_path = './crop_images/origin_imgs1'
save_path = './crop_images/origin_imgs'

if os.path.exists(root_path):
    lst = []
    for filename in os.listdir(root_path):
        i = random.randint(1, 242)
        while i in lst:
            i = random.randint(1, 242)
        lst.append(i)
        # 把图像改名
        old_name = os.path.join(root_path, filename)
        # 保证图片文件名称位数一致
        lens = 5 - len(str(i))
        new_name = os.path.join(save_path, "1" + "0" * (lens - 1) + str(i) + ".jpg")  # 100001
        # 当文件不存在的时候创建,否则会报错:当文件已存在时,无法创建该文件。
        if os.path.exists(new_name):
            print('文件名已存在。')
        else:
            os.rename(old_name, new_name)
        # i += 1

        # 记录修改过程
        filelist = []
        if old_name != new_name:
            filelist.append('Old: ' + old_name)
            filelist.append('New: ' + new_name)

            f = open("rename_log1.txt", "a")
            for file in filelist:
                f.write(file + '\n')

            f.close()
    print('OK')
else:
    print("路径不存在!")


图像旋转/翻转

# 日期:  2023/4/21 20:02
import cv2
import os

import numpy as np
from PIL import Image

root_path = r'D:\datasets\osr_original_img'

for filename in os.listdir(root_path):
    img_path = os.path.join(root_path, filename)
    angle = 270

    # 旋转方式
    # 1
    times = angle // 90
    img = cv2.imread(img_path)  # 生成的是numpy.ndarray,为ndarray多维数组类型,(H,W,C)
    img = np.rot90(img, k=times, axes=(0, 1))  # 对图像矩阵顺时针旋转90度,得到的像素与原来不同,变为H,W,与手机和电脑里对照片的旋转功能相同,如果想要顺时针,k设置为负数
    # 旋转后的图片的保存路径
    if angle == 90:
        new_name = filename.split('.')[0] + '_090.jpg'
    else:
        new_name = filename.split('.')[0] + '_{}.jpg'.format(angle)

    save_path = '../datasets/np rot{}/'.format(angle) + new_name
    # 使用cv2库保存图片,直接对矩阵保存就行
    cv2.imwrite(save_path, img)  # 保存旋转后的图像

    # # 2
    # img = Image.open(img_path)  # 生成的是PIL.JpegImagePlugin.JpegImageFile,(W,H)
    # img = img.transpose(Image.ROTATE_180)  # 引用固定的常量值,得到的像素与原来不同,变为H,W,与手机和电脑里对照片的旋转功能相同

    # 3
    # img = Image.open(img_path)  # 生成的是PIL.JpegImagePlugin.JpegImageFile,(W,H)
    # img = img.rotate(angle)  # 自定义旋转度数,得到的图片的像素与原来一样,都是W,H。逆时针旋转,如果需要顺时针加负号

    # # 旋转后的图片的保存路径
    # if angle == 90:
    #     new_name = filename.split('.')[0] + '_090.jpg'
    # else:
    #     new_name = filename.split('.')[0] + '_{}.jpg'.format(angle)
    #
    # save_path = '../datasets/rotate{}/'.format(angle) + new_name
    # # 使用Image库保存图片
    # img.save(save_path)

关于图像的旋转,有时候容易出现理解偏差,rotate是旋转,Transpose是变换位置,本文用翻转来指代。这两个功能的说明如下:

img.rotate(90) 是旋转90度, 这里要注意,只是对于图像内容进行旋转,图片文件本身(或者可以理解为画布)并不会旋转。
Image.Transpose.ROTATE_90,是翻转90度,通过执行这条语句,整个画布才会翻转。

在使用NumPy库中的np.rot90函数时,第二个参数k表示旋转的次数,如果k是正整数,则将数组旋转k次,如果k是负整数,则将数组逆时针旋转abs(k)次。
而第三个参数axes表示要交换的轴。默认情况下,将交换前两个轴。例如,对于二维数组,将交换第一维和第二维。在这种情况下,不需要指定第三个参数。
但是,当处理的数组不是二维数组时,就需要指定axes参数。在这种情况下,axes应该是一个长度为2的元组,用于指定要交换的轴。例如,在三维数组中,可以将第一维和第二维交换,而第三维保持不变,可以使用axes=(1,0)。
在代码中,-1作为axes参数的值。在这种情况下,-1表示最后一个轴。因此,np.rot90函数将沿着数组的最后一个轴旋转。这相当于在二维数组中,将第一维和第二维交换。

参考1
参考2
参考3
参考4

将图像和对应的xml标签文件都翻转

注释部分是垂直翻转,下面的是水平翻转。

flip_bbox_horizontal 函数的作用是对 XML 标注文件中的矩形框坐标进行水平翻转,并将修改后的标注文件保存到指定路径下。
具体而言,该函数首先使用 ET.parse 函数对传入的 XML 文件进行解析,并获取 XML 文件的根节点。然后,它遍历根节点下的所有 object 节点,对每个节点下的 bndbox 子节点表示的矩形框坐标进行水平翻转。在水平翻转过程中,函数首先获取矩形框的左右两个边界坐标 xmin 和 xmax,然后将 xmin 修改为原图像宽度减去 xmax,xmax 修改为原图像宽度减去 xmin,从而实现矩形框坐标的水平翻转。
最后,函数使用 ET.ElementTree.write 方法将修改后的 XML 标注文件保存到指定路径下。
需要注意的是,该函数的参数 image_width 是用于表示图像宽度的参数,它用于计算矩形框坐标的水平翻转。因此,在调用该函数时,需要将对应图像的宽度传入该参数中。

import os
import xml.etree.ElementTree as ET
from PIL import Image


# def flip_image_vertical(image_path, save_path, output_dir):
#     image = Image.open(image_path)
#     flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM)
#     save_dir = os.path.join(output_dir, os.path.relpath(os.path.dirname(image_path), os.path.dirname(input_image_dir)))
#     if not os.path.exists(save_dir):
#         os.makedirs(save_dir)
#     flipped_image.save(os.path.join(save_dir, os.path.basename(save_path)))
# 
# 
# def flip_bbox_vertical(xml_path, save_path, image_height, output_dir):
#     tree = ET.parse(xml_path)
#     root = tree.getroot()
#     for obj in root.iter('object'):
#         bbox = obj.find('bndbox')
#         ymin = int(bbox.find('ymin').text)
#         ymax = int(bbox.find('ymax').text)
#         bbox.find('ymin').text = str(image_height - ymax)
#         bbox.find('ymax').text = str(image_height - ymin)
#     save_dir = os.path.join(output_dir, os.path.relpath(os.path.dirname(xml_path), os.path.dirname(input_xml_dir)))
#     if not os.path.exists(save_dir):
#         os.makedirs(save_dir)
#     tree.write(os.path.join(save_dir, os.path.basename(save_path)))
# 
# 
# def main(input_image_dir, input_xml_dir, output_image_dir, output_xml_dir):
#     for root, dirs, files in os.walk(input_image_dir):
#         for file in files:
#             if file.endswith('.jpg'):
#                 # 竖直翻转图像
#                 image_path = os.path.join(root, file)
#                 flipped_image_path = os.path.join(os.path.relpath(root, input_image_dir),
#                                                   file.split('.')[0] + '_vertical_flipped.jpg')
#                 flip_image_vertical(image_path, flipped_image_path, output_image_dir)
# 
#                 # 修改XML文件中矩形框坐标
#                 xml_path = os.path.join(input_xml_dir, file.split('.')[0] + '.xml')
#                 flipped_xml_path = os.path.join(os.path.relpath(root, input_image_dir),
#                                                 file.split('.')[0] + '_vertical_flipped.xml')
#                 flip_bbox_vertical(xml_path, flipped_xml_path, Image.open(image_path).size[1], output_xml_dir)
# 
# 
# if __name__ == '__main__':
#     input_image_dir = 'img/image'
#     input_xml_dir = 'img/label'
#     output_image_dir = 'img_vertical_flip/image'
#     output_xml_dir = 'img_vertical_flip/label'
#     if not os.path.exists(output_image_dir):
#         os.makedirs(output_image_dir)
#     if not os.path.exists(output_xml_dir):
#         os.makedirs(output_xml_dir)
#     main(input_image_dir, input_xml_dir, output_image_dir, output_xml_dir)

def flip_image_horizontal(image_path, save_path):
    image = Image.open(image_path)
    flipped_image = image.transpose(Image.FLIP_LEFT_RIGHT)
    flipped_image.save(save_path)


def flip_bbox_horizontal(xml_path, save_path, image_width):
    tree = ET.parse(xml_path)
    root = tree.getroot()
    for obj in root.iter('object'):
        bbox = obj.find('bndbox')
        xmin = int(bbox.find('xmin').text)
        xmax = int(bbox.find('xmax').text)
        bbox.find('xmin').text = str(image_width - xmax)
        bbox.find('xmax').text = str(image_width - xmin)
    tree.write(save_path)


def main(image_dir, xml_dir, output_dir):
    for root, dirs, files in os.walk(image_dir):
        for file in files:
            if file.endswith('.jpg'):
                # 水平翻转图像
                image_path = os.path.join(image_dir, file)
                flipped_image_path = os.path.join(output_dir, file.split('.')[0] + '_flipped.jpg')
                flip_image_horizontal(image_path, flipped_image_path)

                # 修改XML文件中矩形框坐标
                xml_path = os.path.join(xml_dir, file.split('.')[0] + '.xml')
                flipped_xml_path = os.path.join(output_dir, file.split('.')[0] + '_flipped.xml')
                flip_bbox_horizontal(xml_path, flipped_xml_path, Image.open(image_path).size[0])


if __name__ == '__main__':
    image_dir = 'img/image'
    xml_dir = 'img/label'
    output_dir = 'img_flip/output_dir'
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    main(image_dir, xml_dir, output_dir)

将目标所在区域裁剪出来

最后发现方法三好用!

方法一

将玻璃片所在区域裁剪出来。

# 日期:  2023/4/22 14:34
import cv2
import numpy as np

# 读取图片
img_path = r'D:\datasets\osr_original_img\100001.jpg'
img = cv2.imread(img_path)

# 灰度化处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 边缘检测
edges = cv2.Canny(gray, 100, 200)

# 轮廓检测
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 找到矩形轮廓
rect = None
for cnt in contours:
    approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt, True), True)
    if len(approx) == 4:
        rect = approx
        break

# 裁剪矩形区域
if rect is not None:
    rect = rect.reshape(-1, 2)
    x, y, w, h = cv2.boundingRect(rect)
    roi = img[y:y+h, x:x+w]
    cv2.imwrite('D:/your_cropped_image_path.jpg', roi)

代码中的步骤如下:

  1. 读取照片并转换为灰度图像。
  2. 对灰度图像进行边缘检测。
  3. 通过轮廓检测找到接近矩形的轮廓。
  4. 利用矩形轮廓的边界框(bounding box)裁剪出矩形区域。
  5. 将裁剪出的区域保存为新的图片。
    上述代码处理一些图片的时候会使输出全部为黑色。

方法二:

import cv2
import numpy as np

image = cv2.imread(r'D:\datasets\osr_original_img\100018.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

gradX = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=-1)

# subtract the y-gradient from the x-gradient
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)

# blur and threshold the image
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 90, 255, cv2.THRESH_BINARY)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# perform a series of erosions and dilations
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)

(cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]

# compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))

# draw a bounding box arounded the detected barcode and display the image
# cv2.drawContours(image, [box], -1, (255, 255, 255), 2)
cv2.imshow("Image", image)
cv2.imwrite("contoursImage2.jpg", image)
cv2.waitKey(0)

Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
hight = y2 - y1
width = x2 - x1
cropImg = image[y1:y1+hight, x1:x1+width]

cv2.imwrite('D:/your_warped_image_path18.jpg', cropImg)

参考

方法三

import matplotlib.pyplot as plt
import numpy as np
import cv2
import os
import math

# 图像灰度延展、直方图均衡化

file_root = "./osr_original_img"  # 当前文件夹下的所有图片
file_list = os.listdir(file_root)
save_out = "./crop_images/origin_imgs1"  # 保存图片的文件夹名称
for img_name in file_list:
    img_path = file_root + "/" + img_name

    original_image = cv2.imread(img_path, -1)
    image = original_image.copy()
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (3, 3), 0)
    canny = cv2.Canny(blurred, 120, 255, 1)
    kernel = np.ones((9, 9), np.uint8)
    result = cv2.dilate(canny, kernel)
    # Find contours in the image
    cnts = cv2.findContours(result.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    # Obtain area for each contour
    contour_sizes = [(cv2.arcLength(contour, True), contour) for contour in cnts]

    # Find maximum contour and crop for ROI section
    if len(contour_sizes) > 0:
        largest_contour = max(contour_sizes, key=lambda x: x[0])[1]
        # cv2.drawContours(image, largest_contour, -1, (0, 255, 0), 10)
        x, y, w, h = cv2.boundingRect(largest_contour)
        # cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 5)
        ROI = original_image[y-100:y + h + 100, x-100:x + w + 100]

    out_name = img_name.split('.')[0]
    save_path = save_out + "/" + out_name + '.jpg'
    cv2.imwrite(save_path, ROI)

裁剪并纠偏

将玻璃片所在区域裁剪出来。并且把裁剪出来的图片纠偏,因为工业相机拍照的时候会产生畸变。

要将拍摄的图像进行纠偏,使矩形玻璃片在图像中成为矩形,可以使用OpenCV库中的透视变换(perspective transformation)来实现。

下面代码的问题是裁剪纠偏之后的图片相比于原图发生了旋转,像是经过了水平镜像,不知道是否对所有图片都是这样。

import cv2
import numpy as np

# 读取图片
img = cv2.imread(r'D:\datasets\osr_original_img\100002.jpg')

# 灰度化处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 边缘检测
edges = cv2.Canny(gray, 100, 200)

# 轮廓检测
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 找到矩形轮廓
rect = None
for cnt in contours:
    approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt, True), True)
    if len(approx) == 4:
        rect = approx
        break

# 纠偏图像
if rect is not None:
    rect = rect.reshape(-1, 2)
    rect = rect.astype(np.float32)
    (tl, tr, br, bl) = rect
    w1 = np.sqrt((tl[0]-tr[0])**2 + (tl[1]-tr[1])**2)
    w2 = np.sqrt((bl[0]-br[0])**2 + (bl[1]-br[1])**2)
    h1 = np.sqrt((tl[0]-bl[0])**2 + (tl[1]-bl[1])**2)
    h2 = np.sqrt((tr[0]-br[0])**2 + (tr[1]-br[1])**2)
    maxWidth = max(int(w1), int(w2))
    maxHeight = max(int(h1), int(h2))
    dst = np.array([[0, 0], [maxWidth-1, 0], [maxWidth-1, maxHeight-1], [0, maxHeight-1]], dtype=np.float32)
    M = cv2.getPerspectiveTransform(rect, dst)
    warped = cv2.warpPerspective(img, M, (maxWidth, maxHeight))
    cv2.imwrite('D:/your_warped_image_path2.jpg', warped)

代码中的步骤如下:

1.读取照片并转换为灰度图像。
2.对灰度图像进行边缘检测。
3.通过轮廓检测找到接近矩形的轮廓。
4.利用矩形轮廓的边界框裁剪出矩形区域。
5.计算矩形区域的四个顶点在变换后的图像中的位置。
6.利用透视变换(Perspective Transformation)将矩形区域变换为矩形。
7.将变换后的图像保存为新的图片。

在代码中,首先找到了接近矩形的轮廓,并通过轮廓的边界框计算了矩形区域的四个顶点在变换后的图像中的位置。然后,利用cv2.getPerspectiveTransform()函数求得透视变换矩阵M,并使用cv2.warpPerspective()函数将图像进行透视变换。变换后的图像将会是一个矩形,其中玻璃片也将成为一个矩形。

图像扩增方法合集(对单张图片)

注意修改读取和保存图片的路径,并根据需要修改其中的参数。文章来源地址https://www.toymoban.com/news/detail-479435.html

from PIL import Image, ImageEnhance, ImageFilter, ImageDraw
import random

img_path = 'crop_images/0427origin_imgs/100272.jpg'
num = 100272

image = Image.open(img_path)  # 打开图片文件


# 旋转30度

rotated_image = image.rotate(30)  # 将图片旋转30度
rotated_image.save("crop_images/rotated_image_{}.jpg".format(num))  # 保存旋转后的图片文件

# 水平翻转

flipped_image = image.transpose(Image.FLIP_LEFT_RIGHT)  # 将图片水平翻转
flipped_image.save("crop_images/flipped_image_{}.jpg".format(num))  # 保存翻转后的图片文件

# 随机裁剪

width, height = image.size  # 获取图片的宽和高
crop_width, crop_height = 500, 500  # 设定裁剪后的图片大小
left = random.randint(0, width - crop_width)  # 随机生成左上角横坐标
upper = random.randint(0, height - crop_height)  # 随机生成左上角纵坐标
right = left + crop_width  # 计算右下角横坐标
lower = upper + crop_height  # 计算右下角纵坐标
cropped_image = image.crop((left, upper, right, lower))  # 裁剪图片
cropped_image.save("crop_images/cropped_image_{}.jpg".format(num))  # 保存裁剪后的图片文件

# 平移

offset = (50, 50)  # 定义平移量
trans_image = image.transform(image.size, Image.AFFINE, (1, 0, offset[0], 0, 1, offset[1]))  # 对图片进行平移
trans_image.save("trans_image.jpg")  # 保存平移后的图片文件

# 对比度增强

contrast_enhancer = ImageEnhance.Contrast(image)  # 创建对比度增强器
enhanced_image = contrast_enhancer.enhance(1.5)  # 对图片进行对比度增强
enhanced_image.save("contrast_enhanced_image.jpg")  # 保存对比度增强后的图片文件

# 亮度增强

brightness_enhancer = ImageEnhance.Brightness(image)  # 创建亮度增强器
enhanced_image = brightness_enhancer.enhance(1.5)  # 对图片进行亮度增强
enhanced_image.save("brightness_enhanced_image.jpg")  # 保存亮度增强后的图片文件

# 颜色转换


converted_image = image.copy()  # 创建图片副本
r, g, b = converted_image.split()  # 分离图片的RGB通道
r = r.point(lambda i: i + 50)  # 对R通道进行颜色转换
g = g.point(lambda i: i - 30)  # 对G通道进行颜色转换
b = b.point(lambda i: i - 20)  # 对B通道进行颜色转换
converted_image = Image.merge("RGB", (r, g, b))  # 合并三个通道重构图片
converted_image.save("converted_image.jpg")  # 保存颜色转换后的图片文件

# 转换为灰度图

converted_image = image.convert("L")  # 将图片转换为灰度图
converted_image.save("gray_image.jpg")  # 保存灰度图

# 模糊

blurred_image = image.filter(ImageFilter.GaussianBlur(radius=2))  # 对图片进行高斯模糊
blurred_image.save("blurred_image.jpg")  # 保存模糊后的图片文件

# 锐化

sharpened_image = image.filter(ImageFilter.SHARPEN)  # 对图片进行锐化
sharpened_image.save("sharpened_image.jpg")  # 保存锐化后的图片文件

# 添加噪声

draw = ImageDraw.Draw(image)  # 创建绘制对象
width, height = image.size  # 获取图片的宽和高
for x in range(width):
    for y in range(height):
        draw.point((x, y), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))  # 为每个像素点添加随机噪声
image.save("noisy_image.jpg")  # 保存添加噪声后的图片文件


到了这里,关于深度学习中基于python的预处理和图像扩增方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割7(数据预处理)

    在上一节:【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割6(数据预处理) 中,我们已经得到了与 mhd 图像同 seriesUID 名称的 mask nrrd 数据文件了,可以说是一一对应了。 并且, mask 的文件,还根据结节被多少人同时标注,区分成了4个文件夹,分别是标注了一、二、三、四次,

    2024年02月07日
    浏览(46)
  • Pytorch学习笔记(3):图像的预处理(transforms)

      目录  一、torchvision:计算机视觉工具包  二、transforms的运行机制 (1)torchvision.transforms:常用的图像预处理方法 (2)transforms运行原理   三、数据标准化 transforms.Normalize() 四、数据增强  4.1 transforms—数据裁剪 (1)transforms.CentorCrop (2)transforms.RandomCrop (3)RandomResiz

    2023年04月13日
    浏览(42)
  • 如何基于香橙派AIpro对视频/图像数据进行预处理

    本文分享自华为云社区《如何基于香橙派AIpro对视频/图像数据进行预处理》,作者: 昇腾CANN。 受网络结构和训练方式等因素的影响,绝大多数神经网络模型对输入数据都有格式上的限制。在计算机视觉领域,这个限制大多体现在图像的尺寸、色域、归一化参数等。如果源图

    2024年04月22日
    浏览(48)
  • 数据预处理的人工智能与深度学习:如何提高模型性能

    数据预处理是人工智能(AI)和深度学习(DL)领域中的一个关键环节,它涉及到数据清洗、数据转换、数据归一化、数据增强等多种操作,以提高模型性能。在过去的几年里,随着数据规模的增加和复杂性的提高,数据预处理的重要性得到了广泛认识。本文将从以下几个方面进行

    2024年02月19日
    浏览(72)
  • 深度学习中用来训练的train.py 探究学习2.1( 数据预处理)

    下列为mmcls中数据预处理部分  train_pipeline是一个训练过程的配置列表,用于定义数据预处理的步骤。下面是train_pipeline中各个步骤的介绍: 1. LoadImageFromFile:从文件中加载图像。 2. RandomResizedCrop:随机缩放裁剪图像到指定大小。 3. RandomFlip:以一定的概率随机水平翻转图像。

    2024年02月04日
    浏览(51)
  • <2>【深度学习 × PyTorch】pandas | 数据预处理 | 处理缺失值:插值法 | networkx模块绘制知识图谱 | 线性代数初步

      你永远不可能真正的去了解一个人,除非你穿过ta的鞋子,走过ta走过的路,站在ta的角度思考问题,可当你真正走过ta走过的路时,你连路过都会觉得难过。有时候你所看到的,并非事实真相,你了解的,不过是浮在水面上的冰山一角。—————《杀死一只知更鸟》   🎯

    2024年02月01日
    浏览(45)
  • 【Python机器学习】SVM——预处理数据

    为了解决特征特征数量级差异过大,导致的模型过拟合问题,有一种方法就是对每个特征进行缩放,使其大致处于同一范围。核SVM常用的缩放方法是将所有的特征缩放到0和1之间。 “人工”处理方法: 可以看到,最终的结果上训练集和测试集的精度都非常好,但还没有接近

    2024年01月17日
    浏览(39)
  • 【3D 图像分割】基于 Pytorch 的 3D 图像分割6(数据预处理之LIDC-IDRI 标签 xml 标签转储及标记次数统计 )

    由于之前哔站作者整理的 LUNA16 数据处理方式过于的繁琐,于是,本文就对 LUNA16 数据做一个新的整理,最终得到的数据和形式是差不多的。但是,主要不同的是代码逻辑比较的简单,便于理解。 对于 LUNA16 数据集的学习,可以去参考这里:【3D 图像分类】基于 Pytorch 的 3D 立

    2024年02月04日
    浏览(48)
  • 数据挖掘学习——数据预处理方法代码汇总(python)

    目录 一、归一化处理方法 (1)min-max方法(离散归一化) (2)零-均值规范化方法 (3)小数定标规范化 二、插值法 (1)拉格朗日插值法 三、相关性分析 (1)pearson相关性系数 (2)spearman相关性系数 四、主成分分析(PCA) 归一化常用方法有: (1)min-max方法(离散归一化

    2024年02月08日
    浏览(65)
  • 图像预处理算法————灰度化处理

    图像预处理算法适合在FPGA上完成,原理简单且需要快速处理,通常有灰度化、中值、均值滤波等,以及颜色空间转换算法。 灰度图像是一种特殊的彩色图像(R=G=B的彩色图像) 只有一种颜色分量,单通道的0-255 方法:一般有分量法、最大值法、平均值法、加权平均法四种方

    2024年01月17日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包