首页 > 编程语言 >基于opencv-pyhton与opencv-c++的结合理解与学习

基于opencv-pyhton与opencv-c++的结合理解与学习

时间:2023-08-27 22:34:44浏览次数:61  
标签:plt Mat img image cv2 c++ height pyhton opencv

2023年上半年,一直在学习opencv-c++版本,学习了其中的多个库函数

笔记链接:https://www.cnblogs.com/Tan-code/category/2339311.html

  • opencv-python 读取图片,画圆等基本操作 :
  • opencv-c++ 多个库函数:
  • opencv-python与opencv-c++ 结合理解:

结合两段代码来比较实现:

# 导入所需模块
import cv2
from matplotlib import pyplot as plt
import os
import numpy as np
# plt显示彩色图片
def plt_show0(img):
#cv2与plt的图像通道不同:cv2为[b,g,r];plt为[r, g, b]
    b,g,r = cv2.split(img)
    img = cv2.merge([r, g, b])
    plt.imshow(img)
    plt.show()
    
# plt显示灰度图片
def plt_show(img):
    plt.imshow(img,cmap='gray')
    plt.show()

# 图像去噪灰度处理
def gray_guss(image):
    image = cv2.GaussianBlur(image, (3, 3), 0)
    gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    return gray_image

# 读取待检测图片
origin_image = cv2.imread('E:\opencv_practice\licenses.jpg')
# 复制一张图片,在复制图上进行图像操作,保留原图
image = origin_image.copy()
# 图像去噪灰度处理
gray_image = gray_guss(image)
# x方向上的边缘检测(增强边缘信息)
Sobel_x = cv2.Sobel(gray_image, cv2.CV_16S, 1, 0)
absX = cv2.convertScaleAbs(Sobel_x)
image = absX

# 图像阈值化操作——获得二值化图
ret, image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU)
# 显示灰度图像
#plt_show(image)
# 形态学(从图像中提取对表达和描绘区域形状有意义的图像分量)——闭操作
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10))
image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernelX,iterations = 1)
# 显示灰度图像
#plt_show(image)

# 腐蚀(erode)和膨胀(dilate)
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1))
kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20))
#x方向进行闭操作(抑制暗细节)
image = cv2.dilate(image, kernelX)
image = cv2.erode(image, kernelX)
#y方向的开操作
image = cv2.erode(image, kernelY)
image = cv2.dilate(image, kernelY)
# 中值滤波(去噪)
image = cv2.medianBlur(image, 21)
# 显示灰度图像
#plt_show(image)
# 获得轮廓
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
width,height = 600,350  #所需图像大小

for item in contours:
    rect = cv2.boundingRect(item)
    x = rect[0]
    y = rect[1]
    weight = rect[2]
    height = rect[3]
    # 根据轮廓的形状特点,确定车牌的轮廓位置并截取图像,否则提取不到车牌轮廓
    if (weight > (height * 3.5)) and (weight < (height * 4)):
        image = origin_image[y:y + height, x:x + weight]
        

         # 将车牌图像进行透视变换,矫正为矩形形状
        pts1 = np.float32([[0, 0], [weight, 0], [0, height], [weight, height]])
        pts2 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])
        matrix = cv2.getPerspectiveTransform(pts1, pts2)
        warped_image = cv2.warpPerspective(image, matrix, (width, height))
        plt_show0(warped_image)
        cv2.imwrite('E://RM24暑假考核//rect//licenses.jpg',warped_image)

这是c++版的:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

void plt_show0(Mat img) {
    Mat bgr_img;
    cvtColor(img, bgr_img, COLOR_RGB2BGR);
    imshow("Image", bgr_img);
    waitKey(0);
}

void plt_show(Mat img) {
    imshow("Image", img);
    waitKey(0);
}

Mat gray_guss(Mat image) {
    Mat gray_image;
    GaussianBlur(image, image, Size(3, 3), 0);
    cvtColor(image, gray_image, COLOR_RGB2GRAY);
    return gray_image;
}

int main() {
    Mat origin_image = imread("E:\\opencv_practice\\licenses.jpg");
    
    Mat image = origin_image.clone();
    Mat gray_image = gray_guss(image);
    
    Mat Sobel_x,absX;
    Sobel(gray_image, Sobel_x, CV_16S, 1, 0);
    convertScaleAbs(Sobel_x,absX);
    image = absX;
   
    
    threshold(image, image, 0, 255, THRESH_OTSU);
    
    Mat kernelX = getStructuringElement(MORPH_RECT, Size(30, 10));
    morphologyEx(image,image, MORPH_CLOSE, kernelX);
    
    kernelX = getStructuringElement(MORPH_RECT, Size(50, 1));
    Mat kernelY = getStructuringElement(MORPH_RECT, Size(1, 20));
    dilate(image,image, kernelX);
    erode(image, image,kernelX);
    erode(image, image,kernelY);
    dilate(image, image,kernelY);
    
    medianBlur(image,image, 21);
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(image.clone(), contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    int width = 600;
    int height = 350;
    for (const auto& item : contours) {
        Rect rect = boundingRect(item);
        int x = rect.x;
        int y = rect.y;
        int weight = rect.width;
        int height = rect.height;
        
        if (weight > (height * 3.5) && weight < (height * 4)) {
            image = origin_image(Rect(x, y, weight, height));
            
            Mat pts1 = (Mat_<float>(4, 2) << 0, 0, weight, 0, 0, height, weight, height);
            Mat pts2 = (Mat_<float>(4, 2) << 0, 0, width, 0, 0, height, width, height);
            Mat matrix = getPerspectiveTransform(pts1, pts2);
            Mat warped_image;
            warpPerspective(image, warped_image, matrix, Size(width, height));
            plt_show0(warped_image);
            imwrite("E://RM24暑假考核//rect//licenses.jpg", warped_image);
        }
    }
    
    return 0;
}

上面两段代码是关于框出车牌的

个人观点:
python代码中,是不会提前声明一个变量的,而是用的时候直接 img = ...
也就是说,绝大多数函数是有返回值的
而c++不同,许多函数 void function(InputArray,OutputArray,....) ,dstimg是直接写到API里的
但是有些函数还是有返回值的
像是代码中的:

Mat matrix = getPerspectiveTransform(pts1, pts2);
Rect rect = boundingRect(item);

这里还学到个新函数:

image = origin_image(Rect(x, y, weight, height));

这行代码是从原始图像(origin_image)中提取一个矩形区域(Rect)并保存到新的图像变量 image 中。Rect(x, y, width, height) 表示一个矩形,其中 (x, y) 是矩形的左上角坐标,width 是矩形的宽度,height 是矩形的高度。这样,origin_image(Rect(x, y, width, height)) 就表示从 origin_image 中裁剪出指定矩形区域的图像数据,并将其赋值给 image 变量。

标签:plt,Mat,img,image,cv2,c++,height,pyhton,opencv
From: https://www.cnblogs.com/Tan-code/p/17661007.html

相关文章

  • C++—结构体
    8结构体8.1结构体基本概念结构体属于用户自定义的数据类型,允许用户存储不同的数据类型8.2结构体定义和使用语法:struct结构体名{结构体成员列表};通过结构体创建变量的方式有三种:struct结构体名变量名struct结构体名变量名=定义结构体时顺便创建变量总结1:定......
  • C++基础
    一、具备的基础变量(variables):类型(types):int,float,char,struct...作用域(scope)循环(loops):while,for流程控制:if-else,switch-case知道一个程序需要编译、连结才能被执行知道如何编译和连接(如何建立一个可运行程序)二、应当养成正规的、大气的编程习惯以良好的方式编写C++classObj......
  • C++—程序流程结构
    4程序流程结构C/C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构顺序结构:程序按顺序执行,不发生跳转选择结构:依据条件是否满足,有选择的执行相应功能循环结构:依据条件是否满足,循环多次执行某段代码4.1选择结构4.1.1if语句作用:执行满足条件的语句if语句的......
  • C++—指针
    7指针7.1指针的基本概念指针的作用:可以通过指针间接访问内存内存编号是从0开始记录的,一般用十六进制数字表示可以利用指针变量保存地址7.2指针变量的定义和使用指针变量定义语法:数据类型*变量名;指针变量和普通变量的区别普通变量存放的是数据,指针变量存放......
  • C++—数组
    5数组5.1概述所谓数组,就是一个集合,里面存放了相同类型的数据元素特点1:数组中的每个数据元素都是相同的数据类型特点2:数组是由连续的内存位置组成的5.2一维数组5.2.1一维数组定义方式一维数组定义的三种方式:数据类型数组名[数组长度];数据类型数组名[数组长度......
  • C++—函数
    6函数6.1概述作用:将一段经常使用的代码封装起来,减少重复代码一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。6.2函数的定义函数的定义一般主要有5个步骤:1、返回值类型2、函数名3、参数表列4、函数体语句5、return表达式语法:返回值类型函数名(参数列......
  • C++初识
    1.1注释作用:在代码中加一些说明和解释,方便自己或其他程序员程序员阅读代码两种格式单行注释://描述信息通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明多行注释:/*描述信息*/通常放在一段代码的上方,对该段代码做整体说明提示:编译器在编译代码时,会忽......
  • C++空类中有哪些成员函数?
    一共有6个成员函数。1.构造函数2.拷贝构造函数3.析构函数4.赋值运算符5.取址运算符6.取值运算符const1#include<iostream>2usingnamespacestd;34classEmpty5{6Empty();//构造函数7Empty(Empty&);//拷贝构造函数8~Empty();......
  • Windows10 环境下使用 Cmake 和 MinGW-w64 编译安装 OpenCV 4.0.1
    Windows10环境下使用Cmake和MinGW-w64编译安装OpenCV4.0.1翻译搜索复制......
  • cmake学习方法+CHI独占+ctags编写+C/C++语言原子的序+单核比多核快的C代码
    cmake学习方法主要是cmake这个东西好像有点抽象,而我想要的是完完全全的控制,虽然是花里胡哨的;但是在高手看来,这些东西有点过家家,而不是真正意义上的技术,甚至经常被怼,净是花拳绣腿,不容易阅读,控制效果不好,有时候还有语法错误云云。因此我还是用的Makefile,但是想必cmake是更好的,因......