合工大苍穹战队视觉组培训Day2——传统视觉,Opencv基本操作

目录

学习目标

学习内容

学习时间

学习产出

一、思考题

1、OpenCV库与Matlab、halcon的区别?

2、在显示完之后,用不用destroyWindow()有什么区别?

3、png图片格式和jpg图片格式有什么区别?

三、练习题(一解)

1.同时显示两张不同分辨率的图片,对比他们的大小

2.使用Opencv,测试一下你电脑摄像头的分辨率和帧率是多少

3.利用电脑摄像头从外界拍摄一幅自己的图像,添加圆(或其他图形)给自己打码,同时可以通过按键来更改分辨率,并图片右下角添加时间

 三、练习题(二解)

1.同时显示两张不同分辨率的图片,对比他们的大小

2.使用Opencv,测试一下你电脑摄像头的分辨率和帧率是多少

3.利用电脑摄像头从外界拍摄一幅自己的图像,添加圆(或其他图形)给自己打码,同时可以通过按键来更改分辨率,并图片右下角添加时间(python)

学习心得


学习目标

  • 了解Opencv发展历史、Opencv版本区别
  • 掌握图片和视频的读取、显示、保存方法

  • 掌握Opencv基本绘图操作


学习内容

  1. 搭建opencv开发环境
  2. 掌握opencv简单操作

学习时间

  • 2022年7月19日

学习产出

下面是整体学习的过程(代码构建,问题回答过程),在代码实现方面我从C++语言和python语言两个方向入手,整体看来前者较后者较难实现。

搭建环境请参考,写的非常详细:vs2022在win11下配置opencvhttps://blog.csdn.net/Burp_Boom/article/details/124163830?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165823862616782246495908%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165823862616782246495908&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-9-124163830-null-null.142%5Ev32%5Epc_search_v2,185%5Ev2%5Econtrol&utm_term=opencv%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8Bvs2022&spm=1018.2226.3001.4187

一、思考题

1、OpenCV库与Matlab、halcon的区别?


Halcon与OpenCV都是属于函数库,都提供了多种编程语言访问的接口,而Matlab是个完整的集成开发环境,包括了编辑器、函数库、还有Matlab语言。比如用Matlab可以直接Debug,但是用Halcon和OpenCV相关的代码开发就需要配合IDE。Opencv:在识别方面做的比较好,比如人脸识别、视频识别等;Halcon:在尺寸测量方面,感觉Halcon做的比较好,其标定封装的比较好,测量直接可以出来尺寸,还是比较方便的。
 

2、在显示完之后,用不用destroyWindow()有什么区别?


destroyWindow()用于关闭特定的窗口,括号内填写窗口的名字,类型为string。
 

3、png图片格式和jpg图片格式有什么区别?

1.jpg属于有损压缩过的图片文件,是网络中比较流行使用的图片文件格式,jpg格式的图片可以将图像文件压缩到最小格式;png属于无损压缩的图片文件,PNG-8支持透明度,但是不支持半透明,所以PS存储的时候会有杂边颜色。PNG-24支持透明度,支持半透明,存储的文件大小会比PNG-8大。

2.jpg格式的图片能在高度压缩率的同时,可以展现非常生动丰富的图像,不过随着压缩力度的增强,其图片品质会逐渐跌落;但是png图片却不一样,体积小,空间占用少,与jpg格式相比下来,png图片在不损失图片数据的情况下,可以更快速的获取自己所需的图片,并且图片的质量不会因此而下降。
3.png格式的图片可以编辑,比如图片中的文字样式,线条等,可以用ps等软件更改;jpg格式的图片则不可正常编辑。png与jpg图片相比png格式的图片更大。

三、练习题(一解)

1.同时显示两张不同分辨率的图片,对比他们的大小

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
 
using namespace cv;
int main() {
    Mat img  = imread("你的路径1" , 1);
    Mat img1 = imread("你的路径2" , 1);
    printf("图1的分辨率为:%dx%d\n", img.cols, img.rows);
    printf("图2的分辨率为:%dx%d", img1.cols, img1.rows);
    return 0;
}

2.使用Opencv,测试一下你电脑摄像头的分辨率和帧率是多少

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
 
using namespace cv;
int main() {
    VideoCapture capture;
    Mat frame;
    frame= capture.open("你的路径");
    int fps = capture.get(CAP_PROP_FPS);
    int width = capture.get(CAP_PROP_FRAME_WIDTH);
    int height = capture.get(CAP_PROP_FRAME_HEIGHT);
    namedWindow("output", WINDOW_AUTOSIZE);
    while (capture.read(frame))
    {
        imshow("output", frame);
        char ch = waitKey(30);
        if(ch == 27){
            break;
        }
    }
    printf("FPS:%d\n", fps);
    printf("此分辨率为%dx%d",width ,height);
    capture.release();
    return 0;
}

3.利用电脑摄像头从外界拍摄一幅自己的图像,添加圆(或其他图形)给自己打码,同时可以通过按键来更改分辨率,并图片右下角添加时间

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
 
 
int main() {
    double scale_up_x = 1.0;
    double scale_up_y = 1.0;
    int i = 1;
    Mat scaled_f_up, scaled_f_down;
    while(i){
        auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        std::stringstream ss;
        ss << std::put_time(std::localtime(&t), "%Y-%m-%d-%H:%M:%S");
        std::string str_time = ss.str();
 
        Mat pic = imread("/Users/milkman/Desktop/pic1.jpg", 1);
        if (pic.empty())  
        {
            std::cout << "读取失败" << std::endl;
            return -1;
        }
        Point p1(900, 900);
        putText(pic, "milkman", p1, FONT_HERSHEY_COMPLEX, 2, cv::Scalar(0, 0, 0), 3, 8, 0);
        char time = system("time");
        putText(pic, str_time, Point(1000, 700), FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 0), 3, 8, 0);
        rectangle(pic, Point(579, 290), Point(815, 622), cv::Scalar(255, 255, 255), -1);
        imshow("test", pic);
        waitKey(0);
        char ch = waitKey(0);
        if(ch == 38){
            scale_up_x += 0.1;
            resize(pic, scaled_f_up, Size(), scale_up_x, scale_up_y, INTER_LINEAR);
            imshow("scaled_f_up", scaled_f_up);
            waitKey(0);
        }
        if(ch == 40){
            scale_up_y -= 0.1;
            resize(pic, scaled_f_up, Size(), scale_up_x, scale_up_y, INTER_LINEAR);
            imshow("scaled_f_up", scaled_f_up);
            waitKey(0);
        }
        if(ch == 27){
            break;
        }
        scanf("%d", &i);
    }
    return 0;
}
//python
import cv2
import numpy as np

image = cv2.imread('image.jpg')
cv2.imshow('Original Image', image)

down_width = 300
down_height = 200
down_points = (down_width, down_height)
resized_down = cv2.resize(image, down_points, interpolation= cv2.INTER_LINEAR)

up_width = 600
up_height = 400
up_points = (up_width, up_height)
resized_up = cv2.resize(image, up_points, interpolation= cv2.INTER_LINEAR)

cv2.imshow('Resized Down by defining height and width', resized_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining height and width', resized_up)
cv2.waitKey()
//
//C++
#include<opencv2/opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

int main()
{
	Mat image = imread("image.jpg");
	imshow("Original Image", image);

	int down_width = 300;
	int down_height = 200;
	Mat resized_down;
	resize(image, resized_down, Size(down_width, down_height), INTER_LINEAR);
	int up_width = 600;
	int up_height = 400;
	Mat resized_up;
	resize(image, resized_up, Size(up_width, up_height), INTER_LINEAR)
	imshow("Resized Down by defining height and width", resized_down);
	waitKey();
	imshow("Resized Up image by defining height and width", resized_up);
	waitKey();


	destroyAllWindows();
	return 0;
}
//
//cv2.destroyAllWindows()或destroyAllWindows();结束//

 三、练习题(二解)

1.同时显示两张不同分辨率的图片,对比他们的大小

非常遗憾,OpenCV中似乎没有类似Matlab中类似的函数,于是需要我们自定义函数,核心思路是根据需要显示的图像,创建一个新的大图像,使用ROI操作将需要显示的图像复制到新的大图像里。
 

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

using namespace cv;
using namespace std;

Mat combineImages(vector<Mat> imgs,int col,int row,bool hasMargin);//函数声明

int main(){
    vector<Mat> imgs(2);
    imgs[0] = imread("D:/xxxxxx");
    imgs[1] = imread("D:/xxxxxx");

    Mat m = combineImages(imgs, 2, 2, false);
    namedWindow("test",0);
    imshow("test", m);
    //imwrite("D:/research/Test1/rawimage/0.jpg", m);
    waitKey(0);
    return 0;
}

Mat combineImages(vector<Mat> imgs,
                  int col,
                  int row, 
                  bool hasMargin){
    int imgAmount = imgs.size();
    int width = imgs[0].cols;
    int height = imgs[0].rows;
    int newWidth, newHeight;
    if (!hasMargin){
        newWidth = col*imgs[0].cols;
        newHeight = row*imgs[0].rows;
    }
    else{
        newWidth = (col + 1) * 20 + col*width;
        newHeight = (row + 1) * 20 + row*height;
    }

    Mat newImage(newHeight, newWidth, CV_8UC3, Scalar(255, 255, 255));


    int x, y,imgCount;
    if (hasMargin){
        imgCount = 0;
        x = 0; y = 0;
        while (imgCount < imgAmount){
            Mat imageROI = newImage(Rect(x*width + (x + 1) * 20, y*height + (y + 1) * 20, width, height));//创建感兴趣区域
            imgs[imgCount].copyTo(imageROI);
            imgCount++;
            if (x == (col - 1)){
                x = 0;
                y++;
            }
            else{
                x++;
            }
        }
    }
    else{
        imgCount = 0;
        x = 0; y = 0;
        while (imgCount < imgAmount){
            Mat imageROI = newImage(Rect(x*width, y*height, width, height));
            imgs[imgCount].copyTo(imageROI);
            imgCount++;
            if (x == (col - 1)){
                x = 0;
                y++;
            }
            else{
                x++;
            }
        }
    }
    return newImage;
};

2.使用Opencv,测试一下你电脑摄像头的分辨率和帧率是多少

需要注意的是opencv4中未定义标识符CV_CAP_PROP_FPS;CV_CAP_PROP_FRAME_COUNT;CV_CAP_PROP_POS_FRAMES问题,由于opencv版本更新过快,opencv4中有许多标识符发生了更改,对于下列这三个标识符做出如下更改:

CV_CAP_PROP_FPS   ->    CAP_PROP_FPS
CV_CAP_PROP_FRAME_COUNT ->  CAP_PROP_FRAME_COUNT
CV_CAP_PROP_POS_FRAMES ->  CAP_PROP_POS_FRAMES

并且如果前面没有定义cv的命名空间的话(using namespace cv;)则要用cv::CAP_PROP_FRAME_COUNT这种格式。

#include <stdlib.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
int main(int argc, const char** argv)
{
    cv::Mat frame;
    // 可从摄像头输入视频流或直接播放视频文件
    cv::VideoCapture capture(0);
    //    cv::VideoCapture capture("vedio1.avi");
    double fps;
    char string[10]; 
    cv::namedWindow("Camera FPS");
    double t = 0;
    while (1)
    {
        t = (double)cv::getTickCount();
        if (cv::waitKey(1) == 27) { break; }          //#if (cv::waitKey(100) == 27) { break; }
        if (capture.isOpened())
        {
            capture >> frame;
          
            t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
            fps = 1.0 / t;
            sprintf_s(string, "%.2f", fps);      
            std::string fpsString("FPS:");
            fpsString += string;                    
            printf("fps: %.2f width:%d height:%d fps:%.2f\n", fps, frame.cols, frame.rows, capture.get(cv::CAP_PROP_FPS));
            
            cv::putText(frame, // 图像矩阵
                fpsString,                  
                cv::Point(5, 20),           
                cv::FONT_HERSHEY_SIMPLEX,   
                0.5, 
                cv::Scalar(0, 0, 0));       
            cv::imshow("Camera FPS", frame);
        }
        else
        {
            std::cout << "No Camera Input!" << std::endl;
            break;
        }
    }
}

3.利用电脑摄像头从外界拍摄一幅自己的图像,添加圆(或其他图形)给自己打码,同时可以通过按键来更改分辨率,并图片右下角添加时间(python)

原题目是用图片打码,通过摁键更改分辨率但是我的代码一直有bug,所以我做了一个面部处理,设定ROI后,就可以对该区域进行整体操作。此代码将一个感兴趣区域A赋值给变量B后,可以将该变量B赋值给另外一个区域C,从而达到在区域C内复制区域A的目的。
 

import cv2 
import numpy as np

cap = cv2.VideoCapture(0) 

ret,frame = cap.read()

cv2.imshow('cap',frame)

cv2.waitKey()
cv2.destroyAllWindows()

lena=cv2.imread("lena.bmp",0)
h,w=lena.shape
mask=np.zeros((h,w),dtype=np.uint8)
mask[220:400,250:350]=1
key=np.random.randint(0,256,size=[h,w],dtype=np.uint8) 

lenaXorKey=cv2.bitwise_xor(lena,key)  
encryptFace=cv2.bitwise_and(lenaXorKey,mask*255) 
noFace1=cv2.bitwise_and(lena,(1-mask)*255) 
maskFace=encryptFace+noFace1               
extractFace=cv2.bitwise_and(extractOriginal,mask*255)  
noFace2=cv2.bitwise_and(maskFace,(1-mask)*255)  
extractLena=noFace2+extractFace   


cv2.imshow("lena",lena)
cv2.imshow("mask",mask*255)          
cv2.imshow("1-mask",(1-mask)*255)
cv2.imshow("key",key)
cv2.imshow("lenaXorKey",lenaXorKey)
cv2.imshow("encryptFace",encryptFace)
cv2.imshow("noFace1",noFace1)
cv2.imshow("maskFace",maskFace)
cv2.imshow("extractOriginal",extractOriginal)
cv2.imshow("extractFace",extractFace)
cv2.imshow("noFace2",noFace2)
cv2.imshow("extractLena",extractLena)
cv2.waitKey()
cv2.destroyAllWindows()


学习心得

opencv功能的实现用C++比python快,但是难度比python大很多。我觉得我的代码应该不是最简单的最高效,所以哪里有错误请各位斧正,还有一些思路上可能转换不是很好,写好代码的前提还是对编程语言的基本功要扎实,希望我自己可以多学习多写代码,让我的代码慢慢成熟,而且初学opencv一些知识确实比较难,可以去看看B站的视频之类的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工大电科小趴菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值