本文目录导读:

import cv2
import numpy as np
import os
import argparse
from pathlib import Path
def image_to_line_art(image_path, output_path, method='canny',
blur_ksize=5, threshold1=50, threshold2=150,
invert=True, remove_noise=True):
"""
将单张图片转换为线稿
参数:
image_path: 输入图片路径
output_path: 输出图片路径
method: 线稿生成方法 ('canny', 'sobel', 'laplacian', 'adaptive')
blur_ksize: 高斯模糊核大小(奇数)
threshold1: Canny边缘检测的低阈值
threshold2: Canny边缘检测的高阈值
invert: 是否反转颜色(白底黑线)
remove_noise: 是否去除小噪点
"""
# 读取图片
img = cv2.imread(str(image_path))
if img is None:
print(f"错误: 无法读取图片 {image_path}")
return False
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊降噪
if blur_ksize % 2 == 0:
blur_ksize += 1 # 确保是奇数
blurred = cv2.GaussianBlur(gray, (blur_ksize, blur_ksize), 0)
# 边缘检测
if method == 'canny':
edges = cv2.Canny(blurred, threshold1, threshold2)
elif method == 'sobel':
sobelx = cv2.Sobel(blurred, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(blurred, cv2.CV_64F, 0, 1, ksize=3)
edges = cv2.magnitude(sobelx, sobely)
edges = np.uint8(np.clip(edges, 0, 255))
_, edges = cv2.threshold(edges, threshold1, 255, cv2.THRESH_BINARY)
elif method == 'laplacian':
laplacian = cv2.Laplacian(blurred, cv2.CV_64F)
edges = np.uint8(np.clip(np.abs(laplacian), 0, 255))
_, edges = cv2.threshold(edges, threshold1, 255, cv2.THRESH_BINARY)
elif method == 'adaptive':
edges = cv2.adaptiveThreshold(blurred, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 11, 2)
else:
print(f"未知方法: {method},使用默认canny")
edges = cv2.Canny(blurred, threshold1, threshold2)
# 去除小噪点
if remove_noise:
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
min_contour_area = 50
for contour in contours:
if cv2.contourArea(contour) < min_contour_area:
cv2.drawContours(edges, [contour], -1, 0, -1)
# 反转颜色
if invert:
edges = cv2.bitwise_not(edges)
# 保存结果
cv2.imwrite(str(output_path), edges)
return True
def batch_convert(input_dir, output_dir, **kwargs):
"""
批量转换目录中的图片
参数:
input_dir: 输入目录
output_dir: 输出目录
**kwargs: 传递给image_to_line_art的参数
"""
# 支持的图片格式
supported_formats = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.tif'}
# 创建输出目录
Path(output_dir).mkdir(parents=True, exist_ok=True)
# 获取所有图片文件
input_path = Path(input_dir)
image_files = [f for f in input_path.iterdir()
if f.suffix.lower() in supported_formats]
if not image_files:
print(f"在 {input_dir} 中未找到支持的图片文件")
return
# 转换参数
success_count = 0
fail_count = 0
# 常见参数显示
method = kwargs.get('method', 'canny')
threshold1 = kwargs.get('threshold1', 50)
threshold2 = kwargs.get('threshold2', 150)
invert = kwargs.get('invert', True)
print(f"使用方法: {method}, 阈值: {threshold1}/{threshold2}, 反转: {invert}")
for img_file in image_files:
output_file = Path(output_dir) / f"{img_file.stem}_line{img_file.suffix}"
print(f"处理: {img_file.name} -> {output_file.name}")
success = image_to_line_art(img_file, output_file, **kwargs)
if success:
success_count += 1
else:
fail_count += 1
print(f"\n处理完成! 成功: {success_count}, 失败: {fail_count}")
def main():
parser = argparse.ArgumentParser(description='批量转换图片为线稿')
parser.add_argument('input_dir', help='输入图片目录')
parser.add_argument('output_dir', help='输出线稿目录')
parser.add_argument('--method', choices=['canny', 'sobel', 'laplacian', 'adaptive'],
default='canny', help='线稿生成方法 (默认: canny)')
parser.add_argument('--blur', type=int, default=5,
help='高斯模糊核大小 (默认: 5)')
parser.add_argument('--threshold1', type=int, default=50,
help='边缘检测低阈值 (默认: 50)')
parser.add_argument('--threshold2', type=int, default=150,
help='边缘检测高阈值 (默认: 150)')
parser.add_argument('--no-invert', action='store_true',
help='不反转颜色 (默认反转,产生白底黑线)')
parser.add_argument('--keep-noise', action='store_true',
help='保留小噪点 (默认去除)')
args = parser.parse_args()
batch_convert(
args.input_dir,
args.output_dir,
method=args.method,
blur_ksize=args.blur,
threshold1=args.threshold1,
threshold2=args.threshold2,
invert=not args.no_invert,
remove_noise=not args.keep_noise
)
if __name__ == '__main__':
main()
使用方法
安装依赖
pip install opencv-python numpy
基本使用
# 将input文件夹中的图片转换为线稿,输出到output文件夹 python line_art_converter.py input_folder output_folder
高级用法
# 使用自适应阈值方法,调整模糊和阈值 python line_art_converter.py input output --method adaptive --blur 3 # 使用Sobel方法,不反转颜色(黑底白线) python line_art_converter.py input output --method sobel --no-invert # 精细调整Canny阈值 python line_art_converter.py input output --method canny --threshold1 30 --threshold2 100 # 保留噪点 python line_art_converter.py input output --keep-noise
功能特点
-
四种线稿方法:
canny: 经典Canny边缘检测(默认)sobel: Sobel梯度边缘检测laplacian: 拉普拉斯算子边缘检测adaptive: 自适应阈值(适合光照不均的图片)
-
参数调节:
--blur: 模糊程度,值越大线条越粗--threshold1/2: 边缘检测灵敏度
-
输出控制:
- 默认白底黑线(反转)
- 可选黑底白线(
--no-invert) - 自动去除小噪点(可选保留)
脚本会自动处理目录中的所有常见图片格式(jpg、png、bmp、tiff),并在输出文件名后添加_line后缀。