本文目录导读:

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后缀。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播