python opencv:批量识别拼接图片分界线并进行自动裁剪

这篇具有很好参考价值的文章主要介绍了python opencv:批量识别拼接图片分界线并进行自动裁剪。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一 项目概要

在网上找图片素材时,有很多的图片是长图片,在一张图片上拼接了许多张图片,而很多时候我们需要单张图片,此时就需要将长图进行裁剪,一般可以用图片工具进行简单裁剪,高级点可以采用ps进行切片处理,如果图片数量少还好说一旦有大量的图片需要裁剪就很繁琐并且费时费力。这时就会想用自动裁剪工具进行裁剪,而网上的大多数工具都是定尺寸裁剪需要手动输入裁剪位置,这种还是没法实现自动识别图片间的分界线并裁剪的操作。而此时想起曾学习过一点机器视觉的内容,就尝试用python和opencv实现整个操作过程,来识别图片分界线并自动裁剪保存。
python opencv:批量识别拼接图片分界线并进行自动裁剪,opencv,python,计算机视觉

二 项目流程

实现这个过程的大致流程是先扫描给定文件下的所有文件,对扫描出来的文件名进行取后缀处理,将文件后缀与图片类型进行比对,如是图像文件则先将图片转换为灰度图然后去噪,再进行边缘轮廓提取,得到图像边缘轮廓后可以进行图像形态学处理使得分界线更明显,再运用霍夫直线变换进行直线检测,对直线检测的结果进行处理只留下水平直线,将直线的纵坐标提取并以升序排序,排序后进行裁剪保存,如此循环直到将文件夹下的图像文件处理完。而实现以上过程的难点就在于提取出图 片的轮廓。

三 图像边缘提取

由于需要提取图片的边缘轮廓,想到可以用Sobel算子进行处理。图像梯度计算的是图像变化的速度,对于图像的边缘部分,其灰度值变化较大,梯度值也较大;相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小。一般情况下,图像梯度计算的是图像的边缘信息。Sobel 算子是一种离散的微分算子,该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘,计算所得的是一个梯度的近似值。我们想要得到的是水平分界线,可以计算水平垂直方向的偏导数从而得到边缘轮廓。
在opencv中应用sobel算子计算计算图像梯度

import cv2
import numpy as np

# 加载图片并转换为灰度图
img = cv2.imread(r"D:\Image\lsfjlejljlkk (2).jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对灰度图进行高斯模糊
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 使用Sobel算子计算梯度
grad_x = cv2.Sobel(blurred, cv2.CV_16S, 1, 0)
grad_y = cv2.Sobel(blurred, cv2.CV_16S, 0, 1)
# 将梯度转换为绝对值
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
# 合并梯度
grad = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)
# 对梯度进行二值化处理
thresh,binary=cv2.threshold(grad,80,255,cv2.THRESH_BINARY)
cv2.imwrite(r"D:\Image\lsfjlejljlkk (2).jpg", binary,[cv2.IMWRITE_JPEG_QUALITY,98])

图片处理后的结果
python opencv:批量识别拼接图片分界线并进行自动裁剪,opencv,python,计算机视觉
除了应用sobel算子还可以使用Canny 边缘检测

import cv2
import numpy as np

# 加载图片并转换为灰度图
img = cv2.imread(r"D:\Image\lsfjlejljlkk (2).jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#cany处理
cany=cv2.Canny(gray, 50, 150, apertureSize=3)
cv2.imwrite(r"D:\Image\lsfjlejljlkk (3).jpg", cany,[cv2.IMWRITE_JPEG_QUALITY,98])

python opencv:批量识别拼接图片分界线并进行自动裁剪,opencv,python,计算机视觉
从以上结果可以看出来不管是用sobel还是cany,处理后的图像都能明显找出分界线,但仔细观察就会发现图像中除了有分界线还有其他元素,并且分界线不是很连续有锯齿状,可以考虑使用形态学进行处理,先对图像进行膨胀后在进行腐蚀

import cv2
import numpy as np

# 加载图片并转换为灰度图
img = cv2.imread(r"D:\Image\46777cb7e3ae46d6b724b377a6dac721.jpeg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_filtering=cv2.GaussianBlur(gray,(3,3),0,0)
cany = cv2.Canny(gray_filtering, 50, 150, apertureSize=3)
kernel = np.ones((2, 9), np.uint8)
kernel1 = np.ones((1, 40), np.uint8)
cany = cv2.dilate(cany, kernel, iterations=2)
cany = cv2.erode(cany, kernel1, iterations=3)  # 腐蚀
kernel = np.ones((5, 1), np.uint8)
morphology1 = cv2.erode(cany, kernel, iterations=5)
morphology2 = cv2.subtract(cany, morphology1)#相减除去多余元素
cv2.imwrite(r"D:\Image\lsfjlejljlkk (5).jpg", morphology2,[cv2.IMWRITE_JPEG_QUALITY,98])

python opencv:批量识别拼接图片分界线并进行自动裁剪,opencv,python,计算机视觉
经过膨胀腐蚀处理后分界线更加明显,且直线的连续性更好了。

四 直线检测

霍夫变换是一种在图像中寻找直线、圆形以及其他简单形状的方法。霍夫变换采用类似于
投票的方式来获取当前图像内的形状集合,该变换由 Paul Hough(霍夫)于 1962 年首次提出。
最初的霍夫变换只能用于检测直线,经过发展后,霍夫变换不仅能够识别直线,还能识别其他
简单的图形结构,常见的有圆、椭圆等。
本次用opencv提供的函数cv2.HoughLinesP()进行直线检测

import cv2
import numpy as np

Quantity_factor=0.65
Interval_factor=0.25
img = cv2.imread(r"D:\Image\46777cb7e3ae46d6b724b377a6dac721.jpeg")
high=img.shape[0]
wide=img.shape[1]
Quantity =int(Quantity_factor*wide)
Interval =int(Interval_factor*wide)
# 加载图片并转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_filtering=cv2.GaussianBlur(gray,(3,3),0,0)
#使用cany处理图像
cany = cv2.Canny(gray_filtering, 50, 150, apertureSize=3)
kernel = np.ones((2, 9), np.uint8)
kernel1 = np.ones((1, 40), np.uint8)
cany = cv2.dilate(cany, kernel, iterations=2)
cany = cv2.erode(cany, kernel1, iterations=3)  # 腐蚀
kernel = np.ones((5, 1), np.uint8)
morphology1 = cv2.erode(cany, kernel, iterations=5)
morphology2 = cv2.subtract(cany, morphology1)#相减除去多余元素
lines = cv2.HoughLinesP(morphology2,1, np.pi/2,Quantity,maxLineGap=Interval)  #返回值是三维数组
if lines is not None:
    lines_img = new_img(high, wide)
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(lines_img, (x1, y1), (x2, y2), 255, 1)
    cv2.imwrite(r"D:\Image\lsfjlejljlkk (6).jpg", lines_img, [cv2.IMWRITE_JPEG_QUALITY, 98])
else:
    print("没有找到图片裁剪线")

python opencv:批量识别拼接图片分界线并进行自动裁剪,opencv,python,计算机视觉
以上就是找出的图片分界线
最后进行裁剪操作就能得到单张图像了

import cv2
import numpy as np

Quantity_factor=0.65
Interval_factor=0.25
img = cv2.imread(r"D:\Image\46777cb7e3ae46d6b724b377a6dac721.jpeg")
high=img.shape[0]
wide=img.shape[1]
Quantity =int(Quantity_factor*wide)
Interval =int(Interval_factor*wide)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_filtering=cv2.GaussianBlur(gray,(3,3),0,0)

cany = cv2.Canny(gray_filtering, 50, 150, apertureSize=3)
kernel = np.ones((2, 9), np.uint8)
kernel1 = np.ones((1, 40), np.uint8)
cany = cv2.dilate(cany, kernel, iterations=2)
cany = cv2.erode(cany, kernel1, iterations=3)  # 腐蚀
kernel = np.ones((5, 1), np.uint8)
morphology1 = cv2.erode(cany, kernel, iterations=5)
morphology2 = cv2.subtract(cany, morphology1)#相减除去多余元素
lines = cv2.HoughLinesP(morphology2,1, np.pi/2,Quantity,maxLineGap=Interval)  #返回值是三维数组
if lines is not None:
    lines_img = new_img(high, wide)
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(lines_img, (x1, y1), (x2, y2), 255, 1)
    cv2.imwrite(r"D:\Image\lsfjlejljlkk (6).jpg", lines_img, [cv2.IMWRITE_JPEG_QUALITY, 98])
    fenjieY = []
    for lint in range(len(lines)):
        if lines[lint][0][1] == lines[lint][0][3] and lines[lint][0][1] > 0 and lines[lint][0][1] < high - 1:
            fenjieY.append(lines[lint][0][1])
    fenjieY.sort()
    for lie in range(len(fenjieY) - 1):
        if fenjieY[lie + 1] - fenjieY[lie] < 5:
            xz = int((fenjieY[lie] + fenjieY[lie + 1]) / 2)
            fenjieY[lie] = xz
            fenjieY[lie + 1] = xz
    fenjieY.extend([0, high - 1])
    fenjieY = list(set(fenjieY))
    fenjieY.sort()
    for lie in range(len(fenjieY) - 1):
        if fenjieY[lie + 1] - fenjieY[lie] > 500:
            img1 = img[fenjieY[lie]:fenjieY[lie + 1] + 1, 0:wide]
            dizhi = r"D:\Image" + "\\" + "lsfjlejljlkk_" + str(lie) + ".jpg"
            cv2.imwrite(dizhi, img1, [cv2.IMWRITE_JPEG_QUALITY, 98])
else:
    print("没有找到图片裁剪线")

以下就是拆分结果
第一张
python opencv:批量识别拼接图片分界线并进行自动裁剪,opencv,python,计算机视觉
第二张
python opencv:批量识别拼接图片分界线并进行自动裁剪,opencv,python,计算机视觉

五 项目代码

以下程序可以自动运行,只需要提供原始图像文件路径和拆分后的输出路径,若发现效果不理想可以自行更改参数进行调整。文章来源地址https://www.toymoban.com/news/detail-665686.html

import os
import cv2
import numpy as np
#读取文件列表并加载相关参数
img_list=[".jpg",".png",".jpeg",".bmp"]
bassIn_path=r"D:\Image\fen1"
bassOut_path=r"D:\Image\fen1\10"
Quantity_factor=0.65     
Interval_factor=0.25
path_list = os.listdir(bassIn_path)
#Cany处理
def canny(img):
    cany = cv2.Canny(img, 50, 150, apertureSize=3)
    kernel = np.ones((2, 9), np.uint8)
    kernel1 = np.ones((1, 40), np.uint8)
    cany = cv2.dilate(cany, kernel, iterations=2)
    cany = cv2.erode(cany, kernel1, iterations=3)  # 形态学处理 腐蚀
    return cany
#形态学处理
def morphology(img):
    kernel = np.ones((5, 1), np.uint8)
    morphology1 = cv2.erode(img, kernel, iterations=5)  # 形态学处理 腐蚀
    morphology2=cv2.subtract(img, morphology1)
    return morphology2

def new_img(high,wide):
    img = np.zeros((high, wide), np.uint8)
    # 黑色色背景
    img.fill(0)
    return img

#循环处理每个文件
for path_name in path_list:
    if os.path.splitext(path_name)[-1].lower() in img_list:
        iput_path_bass = path_name.replace(os.path.splitext(path_name)[-1],'')
        iput_path=bassIn_path+"\\"+path_name
        # 读入图片
        img = cv2.imread(iput_path)
        print(path_name,"图像属性:",img.shape)
        high=img.shape[0]
        wide=img.shape[1]
        Quantity =int(Quantity_factor*wide)
        Interval =int(Interval_factor*wide)
        # 转为灰度图
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        gray_filtering=cv2.GaussianBlur(gray,(3,3),0,0)
        #进行cany处理
        edges=canny(gray_filtering)
        dizhi1 = bassOut_path + "\\" + iput_path_bass + "_01" + ".jpg"
        cv2.imwrite(dizhi1, edges, [cv2.IMWRITE_JPEG_QUALITY, 98])
        #形态学处理
        edges=morphology(edges)
        dizhi1 = bassOut_path + "\\" + iput_path_bass + "_morphology" + ".jpg"
        cv2.imwrite(dizhi1, edges, [cv2.IMWRITE_JPEG_QUALITY, 98])
        
        #统计概率霍夫线变换
        lines = cv2.HoughLinesP(edges,1, np.pi/2,Quantity,maxLineGap=Interval)  #返回值是三维数组
        #处理直线检测结果
        if lines is not None:
            lines_img=new_img(high,wide)
            for line in lines:
                x1, y1, x2, y2 = line[0]
                cv2.line(lines_img, (x1, y1), (x2, y2), 255, 1)
            dizhi1 = bassOut_path + "\\" + iput_path_bass + "_lines" + ".jpg"
            cv2.imwrite(dizhi1, lines_img, [cv2.IMWRITE_JPEG_QUALITY, 98])
            fenjieY=[]
            for lint in range(len(lines)):
                if lines[lint][0][1]==lines[lint][0][3] and lines[lint][0][1]>0 and lines[lint][0][1]<high-1:
                    fenjieY.append(lines[lint][0][1])
            fenjieY.sort()
            for lie in range(len(fenjieY)-1):
                if fenjieY[lie+1]-fenjieY[lie]<5:
                    xz=int((fenjieY[lie]+fenjieY[lie+1])/2)
                    fenjieY[lie]=xz
                    fenjieY[lie+1]=xz
            fenjieY.extend([0,high-1])
            fenjieY = list(set(fenjieY))
            fenjieY.sort()
            print(path_name,"图像文件处理完成共找到%d条分界线:开始裁剪" % int(len(fenjieY)-2))
            for lie in range(len(fenjieY)-1):
                if fenjieY[lie+1]-fenjieY[lie] > 500:
                    img1 = img[fenjieY[lie]:fenjieY[lie+1]+1, 0:wide]
                    dizhi=bassOut_path+"\\"+iput_path_bass+str(lie)+".jpg"
                    cv2.imwrite(dizhi, img1,[cv2.IMWRITE_JPEG_QUALITY,98])
            print(path_name,"图像裁剪完成")
        else:
            print(path_name,"图像不需要裁剪或者无法找到分界线")



到了这里,关于python opencv:批量识别拼接图片分界线并进行自动裁剪的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 使用Python批量拼接图片

    当需要将多张图像拼接成一张更大的图像时,通常会用到图片拼接技术。这种技术在许多领域中都有广泛的应用,例如计算机视觉、图像处理、卫星图像、地理信息系统等等。在实际应用中,拼接图像可以用于创建全景图像、地图、海报、广告牌等等。 本文将使用以下四张图

    2023年04月15日
    浏览(38)
  • Python Opencv实践 - 全景图片拼接stitcher

            由于手里没有切割好的全景图片资源,因此首先写了一个切片的程序spliter。         如果有现成的切割好的待拼接的切片文件,则不需要使用spliter。         对于全景图片的拼接,需要注意一点,各个切片图片之间要有重复的内容以便opencv能够提取到关键点并

    2024年02月22日
    浏览(49)
  • Python 结合opencv实现图片截取和拼接

    python 3.6.2 scikit-build-0.16.7 win10 opencv_python-4.5.4.60-cp36-cp36m-win_amd64.whl 下载地址: https://pypi.org/project/opencv-python/4.5.4.60/#files https://files.pythonhosted.org/packages/57/6c/7f4f56b2555d5c25dd4f41fc72a16dc6402cb2b4f967da11d8d26c669b55/opencv_python-4.5.4.60-cp36-cp36m-win_amd64.whl 注意:下载时不用下abi版的,比如 o

    2024年02月08日
    浏览(44)
  • 自动驾驶采集多视角图像处理(python实现不同文件夹下同名图片批量拼接并生成视频)

    目录 1.图像拼接 2.合成视频 2.1 cv2.videowriter_fourcc功能介绍 2.2读取图片合成视频 实现目标:将自动驾驶车6个摄像头采集到的图片,按照正确顺序拼接显示,nuScenes数据集测试如下: 图像存放文件夹目录如下: 每个目录下有相同名称,不同视角采集到的图像 。 先显示图片,代

    2024年01月18日
    浏览(66)
  • Python批量识别图片文字(数字识别模式)大幅度提高数字识别准确率

    目录   一、使用beautiful soup库爬取网页图片 二、使用pytesseract库识别图片中数据,并将数据存入txt文件 三、用pandas库实现txt文件到csv文件的转换   一、使用beautiful soup库爬取网页图片  该网站中有需要的数据,但是是以图片形式存在。 这样就给我们爬取数据造成了一些困扰

    2024年02月13日
    浏览(43)
  • 【Python 实战】---- 批量识别图片中的文字,存入excel中【使用百度的通用文字识别】

    1. 获取信息图片示例 2. 运行实例 3. 运行结果 4. 各个文件的位置 1. 需求分析 识别图片中的文字【采用百度的通用文字识别】; 文字筛选,按照分类获取对应的文本; 采用 openpyxl 实现将数据存入 excel 中。 2. 获取 access_token 获取本地缓存的

    2024年02月15日
    浏览(49)
  • 基于 Opencv python实现批量图片去黑边—裁剪—压缩软件

    批量处理图片文件,批量提取GIF图片中的每一帧,具有范围裁剪、自动去除黑/白边、调整大小、压缩体积等功能。 先看一些软件的界面,是基于Tkinter写的GUI 裁剪等功能基于Opencv     我添加了处理GIF的github:  原作者的github:hiroi-sora/Umi-CUT: 图片批量去黑边/裁剪/压缩工具,

    2024年02月15日
    浏览(44)
  • 使用opencv批量人脸识别+裁图+设置分辨率(Python代码分享)

    最近做LoRA模型训练时需要对一批图片进行人脸识别,并进行裁剪,然后设置特定的分辨率。 首先要导入cv库 import cv2 如果没有opencv库的话要用pip先安装一个 pip install opencv-python 1、识别出图片面部,并截取原图片靠近面部的最大正方形部位,同时将截取的图片分辨率改为512*

    2024年02月12日
    浏览(63)
  • Python Opencv 图片识别表格:边框线检测

    Python数据开发工作需求对图片做边框线检查和图片中的直线,非常实用建议收藏 下面需要用模块,先安装一下: 该示例代码使用边缘检测和霍夫变换提取图片中的直线,然后根据直线数量来判断是否有表格。这只是一个简单的示例,具体的判断方法和算法需要根据具体情况

    2024年02月16日
    浏览(41)
  • (OpenCV)图片拼接

            图片拼接在许多领域都有广泛的应用,包括但不限于以下几个方面: 全景摄影 :在摄影中,通过将多张照片拼接在一起可以实现全景照片的效果。这在旅游景点、房地产展示等领域有着广泛的应用,能够提供更加生动、真实的视觉体验。 医学影像处理 :在医学

    2024年02月22日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包