Opencv实现倾斜图片转正示例

今天是我们来玩一个钉子。通过一个钉子来学习一个opencv中的一个函数,这个函数我网上也有搜过,不过遗憾的是,各路好手都是写的是有点不堪入目,现在这个学习氛围是越来越差了,很多人都直接复制粘贴别人的东西,自己也没有理解,也没有辨别是非的能力,所谓的拿来主义有时候真的是要不得的。知其然也要知其所以然。所以你很多时候遇到问题去网上搜索的时候,你会发现浏览器上面一排网页,好多内容都是相同,甚至是错的,这样很不好。

闲话不多说,我们今天通过一个实例来,讲解一个网上很多人都没搞清楚的函数cv2.minAreaRect()

我们用到图片

我们要做的事情是将这个钉子转成水平放心放置,然后抠出钉子的区域,就像下面这个样子

实现步骤:

1.灰度化+二值化,效果图如下

2.找轮廓,cv2.findcounters(),这样的图我们肯定会找到很多轮廓,所以我们可以通过面积来筛选出自己想要的那个轮廓,这里我们选择最大的轮廓,也就是钉子的轮廓,看看效果(红线就是哦我们找到的轮廓点然后连接起来的)

3.找这个轮廓的最小外接矩形(带角度),这个就是最关键的了,也就是我们开头提到的cv2.minAreaRect(),我们要对他的返回值了如执掌。先看看效果呢(蓝线就是我们找到的最小外接矩形)

这个时候你会说,这有什么难的,我们来细细看一下,cv2.minAreaRect()的返回值是什么

box= cv2.minAreaRect(counter)
print(box)

我们看看这个返回值是一个元组

((257.3854675292969, 292.03851318359375), (454.5963439941406, 140.96072387695312), 48.21548080444336)

元组的第一个元素是这个最小外接矩形的中心点坐标

元组的第二个元素是也是一个元组,这个元组是最小外接矩形的两个边长(注意是两个边长,并不是宽高),这个时候你就会问了,这有什么区别,看上去是没什么区别,其实是由返回顺序的,有的时候长的那条边在这个元组的第一个元素位置,有的时候长的那条边在这个元组的第二个元素位置。不信我在给你看一个返回值

((290.1945495605469, 256.9798889160156), (140.9435577392578, 460.39862060546875), 49.1729850769043)

元组的第三个元素是一个浮点数,这个浮点数也就是这个外接矩形的角度,那么,这个角度又是哪个边的与X轴的角度呢?答案是要根据第二个元组的值长短边的顺序来决定的,这个角度始终是第二元组中第一个元素对应的那条边和x的夹角。而且这个角度永远是大于0的。网上有人说是-90-90°,说实话,经过测试,我们见到负角度的,那些人可能试都没试吧。也就是这个角度。

我想我已经说明白了

4.根据得到的中心点和角度以及第二个元组的值的大小就可以开始旋转了

值得注意的是,opencv中旋转是逆时针旋转,所以在旋转的时候要注意旋转的角度,看看效果

5.有中心点和两条边长的大小,我们就可以开始抠图了,看看效果

至此Mission accomplished。

我们上代码吧

# -*- coding: utf-8 -*-
# @Time : 2022/7/25 15:51
# @Author : guligedong
import cv2
import os
import numpy as np

base_folder = r'F:\mvtec_anomaly_detection\screw\test\good'
for i in os.listdir(base_folder):
    img_path = os.path.join(base_folder, i)
    if img_path.split('.')[-1] == 'db':
        continue
    print(img_path)
    img = cv2.imread(img_path)
    img = cv2.resize(img,(512,512))
    img_h,img_w = img.shape[:2]
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _,bi_img = cv2.threshold(gray_img,127,255,cv2.THRESH_BINARY_INV)

    counters,_ = cv2.findContours(bi_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    for index,counter in enumerate(counters):
        if cv2.contourArea(counter) > 10000 :
            cv2.drawContours(img,counters,index,(0,0,255),1)
            box= cv2.minAreaRect(counter)
            print(box)
            boxs= cv2.boxPoints(box)
            boxs = np.int0([boxs])
            print(boxs)
            cv2.polylines(img, boxs, isClosed=True, color=(255, 125, 125), thickness=1)
            cv2.imshow('img', img)
            # cv2.waitKey()
            center_x,center_y = int(box[0][0]),int(box[0][1])
            lenth1, lenth2 = int(box[1][0]), int(box[1][1])
            print(lenth1, lenth2)
            angle = box[2]
            print(angle)
            if lenth1 > lenth2:
                angle  = angle
            else:
                angle = -(90 - angle)
            rotate_matrix = cv2.getRotationMatrix2D(center=(center_x,center_y),angle=angle,scale=1)
            rotated_image = cv2.warpAffine(src=img, M=rotate_matrix, dsize=(img_w, img_h))
            cv2.imshow('Rotated image', rotated_image)
            y_start = center_y - min(lenth1, lenth2) // 2 if center_y - min(lenth1, lenth2) // 2 > 0 else 0
            y_end = center_y + min(lenth1, lenth2) // 2 if center_y + min(lenth1, lenth2) // 2 < img_h else img_h
            x_start = center_x - max(lenth1, lenth2) // 2 if center_x - max(lenth1, lenth2) // 2 >0 else 0
            x_end = center_x + max(lenth1, lenth2) // 2 if center_x + max(lenth1, lenth2) // 2 <img_w else img_w
            crop_image = rotated_image[y_start:y_end,x_start:x_end]
            cv2.imshow('crop_image', crop_image)
            cv2.waitKey()

这个数据是mvtec_anomaly_detection数据集中的钉子的数据集,大家可以网上找资源试一试小效果,关键是要自己理解这个逻辑。

到此这篇关于Opencv实现倾斜图片转正示例的文章就介绍到这了,更多相关Opencv 倾斜图片转正内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • opencv resize图片为正方形尺寸的实现方法

    在深度学习中,模型的输入size通常是正方形尺寸的,比如300 x 300这样.直接resize的话,会把图像拉的变形.通常我们希望resize以后仍然保持图片的宽高比. 例如: 如果直接resize到的话: 而我们希望得到: 可以利用copyMakeBorder和resize配合达到我们的目的. import cv2 def resize_keep_aspectratio(image_src,dst_size): src_h,src_w = image_src.shape[:2] print(

  • OpenCV 使用imread()函数读取图片的六种正确姿势

    经常看到有人在网上询问关于imread()函数读取图片失败的问题.今天心血来潮,经过实验,总结出imread()调用的四种正确姿势. 通常我要获取一张图片的绝对路径是这样做的:在图片上右键--属性--安全--对象名称.然后复制对象名称就得到了图片的绝对路径. 如图: 然而这样得到的路径直接复制粘贴到vs里面会直接报错,如下: 可以看出我们获取的绝对路径的表示方法是单右斜线形式的.显然opencv的imread()不支持这种方式.但是!!!经过实验发现imread()除了不支持单右斜线形式,其他斜

  • opencv利用霍夫变换检测直线进行图片校正

    利用霍夫变换检测直线,校正拍摄倾斜的图片 #include<opencv2\opencv.hpp> #include <iostream> using namespace cv; using namespace std; #define ERROR 1234 //度数转换 double DegreeTrans(double theta) { double res = theta / CV_PI * 180; return res; } //逆时针旋转图像degree角度(原尺寸)

  • python中opencv实现图片文本倾斜校正

    本项目为python项目需要安装python及python的opencv模块:opencv_python-4.0.1-cp37-cp37m-win32.whl 和 python的矩阵运算模块:numpy. 1.第一步,安装python3.7,具体安装步骤略. 2.第二步,使用pip安装python的矩阵运算模块:numpy. python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose

  • Opencv实现倾斜图片转正示例

    今天是我们来玩一个钉子.通过一个钉子来学习一个opencv中的一个函数,这个函数我网上也有搜过,不过遗憾的是,各路好手都是写的是有点不堪入目,现在这个学习氛围是越来越差了,很多人都直接复制粘贴别人的东西,自己也没有理解,也没有辨别是非的能力,所谓的拿来主义有时候真的是要不得的.知其然也要知其所以然.所以你很多时候遇到问题去网上搜索的时候,你会发现浏览器上面一排网页,好多内容都是相同,甚至是错的,这样很不好. 闲话不多说,我们今天通过一个实例来,讲解一个网上很多人都没搞清楚的函数cv2.minAr

  • C++ opencv图像处理实现图片几何变换示例

    目录 简介 一.图像平移 1.图像平移代码 (不改变图像大小) 2.图像平移代码 (改变图像大小) 二.图像旋转 1.图像旋转函数 2.仿射变换函数 3.代码 三.图像缩放 1.图像缩放函数 2.图像缩小代码 3.图像放大代码 总结 简介 图像的几何变换不改变图像的像素值,而是改变像素所在的几何位置,从变换的性质来分,图像的几何变换有图像的位置变换(平移,镜像,旋转).图像的形状变换(放大,缩小,错切)等基本变换,以及图像的复合变换等, 一.图像平移 图像平移是将一幅图像中所有的点都按照指定的平

  • C++ opencv图像处理实现图片边缘检测示例

    目录 边缘检测简介 一.边缘检测步骤 二.Canny 1.函数 2.代码 二.Sobel 1.函数 2.代码 三.Scharr 1.函数 2.代码 四.Laplacian 1.函数 2.代码 总结 边缘检测简介 边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点. 图像边缘检测大幅度地减少了数据量,并且剔除量不相关的信息,保留了图像重要的结构属性. 一.边缘检测步骤 1.图像获取 2.图像滤波 3.图像增强 4.图像检测 5.图像定位 二.Canny 1.

  • 用OpenCV将视频分解成单帧图片,图片合成视频示例

    本文做的是基于opencv将视频帧转成图片输出,由于一个视频包含的帧数过多,经常我们并不是需要它的全部帧转成图片,因此我们希望可以设置每隔多少帧再转一次图片(本文设置为30帧),若有人需求是只需要前多少帧,也可以类似的改写下代码即可. 程序一: #include <iostream> #include "cv.h" #include "opencv2/opencv.hpp" using namespace std; using namespace cv;

  • Python+Opencv实现把图片、视频互转的示例

    1. 安装Opencv包 pip install opvencv-python 2.实现代码: 视频转为图片: import cv2 cap=cv2.VideoCapture('E:/video/video-02.mp4') # 获取一个视频打开cap isOpened=cap.isOpened # 判断是否打开 print(isOpened) fps=cap.get(cv2.CAP_PROP_FPS) print(fps) # 获取宽度 width=int(cap.get(cv2.CAP_PR

  • OpenCV自动给图片添加彩虹特效的实现示例

    目录 背景介绍  实现步骤 [1]准备一张夏季风景图片,加载读取 [2]创建一张与原图同样大小的黑图,然后通过画椭圆函数绘制彩虹 [3]高斯模糊,让彩虹边缘更柔和过渡 [4]彩虹图像与风景图混合叠加(使用泊松融合效果更佳) 背景介绍 南方的冬季总是淅淅沥沥下着小雨,晴天渐渐成为奢望.此时,我多么希望感受一下夏季的温暖,哪怕是雨天,偶尔还会看到彩虹!想到这便动起手来,找找夏季的照片和视频,用OpenCV给它们加上漫天彩虹.  实现步骤 [1]准备一张夏季风景图片,加载读取 Mat src = im

  • C++ opencv实现在图片上画一条线示例代码

    1 在图片上用鼠标进行操作,opencv主要用到setMouseCallback()函数. winname 窗口名称 onMouse 鼠标事件的回调函数 userdata 传递给回调函数 还有onMouse函数 event 鼠标事件 x,y 鼠标在图片上的坐标 flags 鼠标事件标志 这里有一个容易搞混的地方 void跟void* 在函数的返回值中, void 是没有任何返回值, 而 void * 是返回任意类型的值的指针. 划线还需要用到line()函数 img 图片名称 pt1 线段起点

  • Python opencv应用实现图片切分操作示例

    目录 说明 操作说明 代码 切换效果 说明 之前下载来zip包的漫画,里面的图片都是两张一起的: 但是某些漫画查看软件不支持自动分屏,看起来会比较不舒服,所以只能自己动手来切分. 操作说明 Python有不少的库支持图片操作,其中比较著名的一个是OpenCV. OpenCV是一个跨平台的计算机视觉库,Python下有它的接口实现. Python默认不带OpenCV,所以需要先用pip下载: OpenCV功能强大,这里用来做图片的切分其实是牛刀小试. 关于OpenCV的功能,这里不多介绍,有兴趣的

  • Python+Opencv实现数字识别的示例代码

    一.什么是数字识别?   所谓的数字识别,就是使用算法自动识别出图片中的数字.具体的效果如下图所示: 上图展示了算法的处理效果,算法能够自动的识别到LCD屏幕上面的数字,这在现实场景中具有很大的实际应用价值.下面我们将对它的实现细节进行详细解析. 二.如何实现数字识别?   对于数字识别这个任务而言,它并不是一个新的研究方向,很久之前就有很多的学者们在关注这个问题,并提出了一些可行的解决方案,本小节我们将对这些方案进行简单的总结. 方案一:使用现成的OCR技术. OCR,即文字识别,它是一个比较

  • opencv调整图像亮度对比度的示例代码

    图像处理 图像变换就是找到一个函数,把原始图像矩阵经过函数处理后,转换为目标图像矩阵. 可以分为两种方式,即像素级别的变换和区域级别的变换 Point operators (pixel transforms) Neighborhood (area-based) operators 像素级别的变换就相当于\(p_{after}(i,j) = f(p_{before}(i,j))\),即变换后的每个像素值都与变换前的同位置的像素值有个函数映射关系. 对比度和亮度改变 线性变换 最常用的是线性变换.即

随机推荐