Mat使用笔记

2023-11-16

一.基本操作

1.1 创建

cv::Mat初识和它的六种创建方法

cv::Mat matDes(nHEIGHT,nWID,CV_8UC1, cv::Scalar(0));//创建 row(高),col(宽)
cv::Mat matDes = cv::Mat::zeros(nHEIGHT,nWID,CV_8UC1);//创建 黑色矩阵 matlap方法
m_Mat.create(nRow, 1000, m_MatImg.type());//, cv::Scalar(0)
matDes=cv::Mat(nImgH,nImgW,CV_8UC1,cv::Scalar(255));

1.2 Mat保存

std::vector <int> compression_params;
compression_params.push_back(259);
if(0 == m_nImgType){
    compression_params.push_back(1);//1-无压缩
}
else if(1 == m_nImgType){
    compression_params.push_back(5);//5-COMPRESSION_LZW
}

cv::imwrite(sPath.toStdString(),mat,compression_params);//默认替换现有文件

1.2 遍历Mat

int nRows = matSrc.rows,nCols = matSrc.cols;
    int nMatType = matSrc.type();
    if(0 == nMatType){//CV_8UC1
        uchar* pDataSrc = NULL;
        for (int i = 0; i< nRows; i++)
        {
            pDataSrc = matSrc.ptr<uchar>(i);
            if(pDataSrc ==NULL) continue;            
            for (int j = 0; j < nCols; j++)
            {
                pDataSrc[j]=cv::saturate_cast<uchar>(m_nMax-pDataSrc[j]);//
            }
        }
    }
    else if(2 == nMatType){//CV_16UC1
        ushort* pDataSrc = NULL;
        for (int i = 0; i< nRows; i++)
        {
            pDataSrc = matSrc.ptr<ushort>(i);
            if(pDataSrc ==NULL) continue;            
            for (int j = 0; j < nCols; j++)
            {
                pDataSrc[j]=cv::saturate_cast<ushort>(m_nMax-pDataSrc[j]);//
            }
        }
    }

1.4 Mat的部分赋值剪贴

cv::Mat DesROIMat =matDes(cv::Rect(nX2,nY2,nWid,nHeight)); //范围时 宽,高
matSrc.copyTo(DesROIMat);//深复制? 位数不一致会导致copy失败

1.5 判断Mat有效性/是否加载成功

matFile.empty()
nullptr==matFile.data

1.6 16位Mat转8位

void oeThread_LS::Mat16ToMat8(cv::Mat &mat16,cv::Mat &mat8)
{
   Mat tmp;
   mat8 = Mat::zeros(mat16.size(), CV_8U);
   normalize(mat16, tmp, 0, 255, NORM_MINMAX);
   convertScaleAbs(tmp, mat8);
}

1.7 Mat旋转90度-逆时针

//顺时针90度+沿y轴翻转
transpose(matFileCut, matCopy);//顺时针90度+沿y轴翻转
//flip(matCopy, matCopy, 0);//逆时针90度
//flip(matCopy, matCopy, 1);//顺时针90度
 //flip(matFile, matCopy,-1);//顺时针90度+沿y轴翻转 / 逆时针90度+沿x轴翻转
 
//沿y轴翻转
transpose(matFileCut, matCopy);//顺时针90度+沿y轴翻转  
flip(matCopy, matCopy, 1);//顺时针90度

1.8 Mat的缩放

int nRow = matSrc.rows*fScale;
int nCol = matSrc.cols*fScale;
cv::Mat matDes(nRow,nCol,CV_8UC3,cv::Scalar(0));//先分配内存,否则无效Mat致崩
cv::resize(matSrc,matDes,matDes.size());

二.常见问题记录

2.1 Mat致崩

如cv::resize范围不合理致崩,但不明确定位报错。

2.2 cv::imread读取异常

A.Debug下无带d的cv库。
B.读、写16位tif得到图片全白(读取图片类型、默认灰度值,文件后缀保存时一致)。
C.|与||,按位或与逻辑或,结果分别为二进制数和bool,此处用前者|。
D.读取中文路径,sPath.toLocal8Bit().toStdString(),cv::imwrite类似。

cv::Mat matSrc=cv::imread(sJpgPath.toStdString(),cv::IMREAD_GRAYSCALE|cv::IMREAD_ANYDEPTH);

//0 pow(256,matSrc.type())-1
cv::Mat matDes(nHEIGHT,nWID,matSrc.type(),cv::Scalar(0));//CV_8UC1创建 0黑255白 row,col

cv::Mat DesROIMat =matDes(cv::Rect(nX2,nY2,nWid,nHeight));//越界致崩
matSrc.copyTo(DesROIMat);//深复制? Mat的部分赋值(剪贴)

 QString sDesPath = m_sPathOut + "/"+fileInfo.baseName()+'.'+fileInfo.suffix();
 cv::imwrite(sDesPath.toStdString(),matDes);//无.jpg后缀会致崩

三.加载BigTif

修改opencv位限制长度。
BigTif右键不能看到具体属性信息,也看不到缩略图。
Debug BigTif8可打开,BigTif16可打开

Debug Release
BigTif8可打开 BigTif8可打开
BigTif16可打开 BigTif16不可打开,借助相关库
cv::Mat oeToolMat::ReadBigTif(QString sPath)
{
    cv::Mat ImageMat;

    int i, nret, nw, nh, nbpp, npage = 1;
    TIFF* tif;
    tif = TIFFOpen(sPath.toStdString().c_str(), "r");
    if (tif)
    {
        TIFFSetDirectory(tif, 1); // 跳到指定的页数1
        int iRett = TIFFIsBigTIFF(tif);//

        int iRow, iCol, iBitsPerChannel, iChannels, iComp;
        nret = TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &iCol); // 获取图像长、宽
        nret = TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &iRow);
        nret = TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &iBitsPerChannel);
        nret = TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &iChannels);
        nret = TIFFGetField(tif, TIFFTAG_COMPRESSION, &iComp);//5 LZW

        int scanlineSize = TIFFStripSize(tif);
        int nStrip = TIFFNumberOfStrips(tif);
        uint32* bc; // wrong size??
        nret = TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);

        int iDepth = CV_8UC1;
        if (iBitsPerChannel == 8)
        {
            iDepth = CV_8UC1;
        }
        else if (iBitsPerChannel == 16)
        {
            iDepth = CV_16UC1;
        }

        npage = TIFFNumberOfDirectories(tif); // 读取页数
        ImageMat.create(iRow, iCol, iDepth);

        tdata_t buf;
        uint32 row;

        buf = _TIFFmalloc(TIFFScanlineSize(tif));
        for (row = 0; row < iRow; row++)
        {
            TIFFReadScanline(tif, buf, row);
            memcpy(ImageMat.data + ImageMat.step * row, buf, scanlineSize);
        }
        _TIFFfree(buf);
        TIFFClose(tif);
    }

    return ImageMat;
}

四.Mat传参

4.1 Qt信号槽需先注册Mat

#include <QMetaType>
qRegisterMetaType< cv::Mat >("cv::Mat&");//()内cv::Mat&或cv::Mat皆可

传cv::Mat&正常。
传cv::Mat异常

void RunProcess::Rotate(cv::Mat& ImageSrc)
{
    cv::imwrite(QString("D:/1.tif").toStdString(),ImageSrc);  
        transpose(ImageSrc,ImageSrc);//顺时针90度+沿y轴翻转
        flip(ImageSrc,ImageSrc,0);//逆时针90度
        flip(ImageSrc,ImageSrc,1);//顺时针90度

    cv::imwrite(QString("D:/2.tif").toStdString(),ImageSrc);
}

4.2 传入Mat修改

传cv::Mat&/cv::Mat失败,return cv::Mat成功。
猜测
1.形参image为临时副本,只读不修改。
2.warpAffine造成。

cv::Mat  RunProcess::Rotate(cv::Mat image, int degree)
{
	cv::Mat M,dst= image.clone();//猜测该函数结束后会释放
	int h = image.rows;
	int w = image.cols;
	M = getRotationMatrix2D(cv::Point2f(w / 2, h / 2), degree, 1.0);//定义变换矩阵M 45
	double cos = abs(M.at<double>(0, 0));	//求cos值
	double sin = abs(M.at<double>(0, 1));	//求sin值
	int nw = cos * w + sin * h;		//计算新的长、宽
	int nh = sin * w + cos * h;
	M.at<double>(0, 2) += (nw / 2 - w / 2);		//计算新的中心
	M.at<double>(1, 2) += (nh / 2 - h / 2);
	warpAffine(image, dst,M,cv::Size(nw, nh), cv::INTER_LINEAR, 0, cv::Scalar(255));//,255,255
	image = dst.clone();
	return dst;
}
//传cv::Mat &image 成功
void RunProcess::Rotate3(cv::Mat &image, int degree)
{
	cv::Mat M;//dst,
	int h = image.rows;
	int w = image.cols;
	M = getRotationMatrix2D(cv::Point2f(w / 2, h / 2), degree, 1.0);//定义变换矩阵M 45
	double cos = abs(M.at<double>(0, 0));	//求cos值
	double sin = abs(M.at<double>(0, 1));	//求sin值
	int nw = cos * w + sin * h;		//计算新的长、宽
	int nh = sin * w + cos * h;
	M.at<double>(0, 2) += (nw / 2 - w / 2);		//计算新的中心
	M.at<double>(1, 2) += (nh / 2 - h / 2);
	warpAffine(image, image, M, cv::Size(nw, nh), cv::INTER_LINEAR, 0, cv::Scalar(0));//,255,255
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mat使用笔记 的相关文章

  • 针对不同相机(RGB 和红外)的 StereoCalibrate

    我在校准两个摄像头时遇到问题 第一个是 RGB 第二个是红外 它们有不同的分辨率 我调整了大小并裁剪了更大的图像 焦距等等 例子 RGB 1920x1080 Infrared 512x424 如何相互校准它们 我应该在stereoCalib
  • 使用 Unity3D 解决 PnP

    我有一个真实 物理的棍子 上面连接有红外摄像头和一些红外 LED 它们形成了我正在使用的模式 以便使虚拟棍子以与物理棍子相同的方式移动 为此 我在 Python 中使用 OpenCV 并将由solvePnP 计算的旋转和平移向量发送到 Un
  • 从视频/图像中提取元数据

    我从 IP 摄像机获取 MJPEG 流 我正在查看该流并将其保存在计算机上 可以找到我的操作代码here https stackoverflow com questions 21702477 how to parse mjpeg http
  • OpenCV 中“IplImage”和“CvMat”的全称是什么?

    有一个IplImage and CvMat在 OpenCV 中 他们的全名是什么 IPL in IplImage代表英特尔处理库 这是Intel维护OpenCV时的残余 CV in cvMat代表计算机视觉矩阵 这是图形中常用的数据结构 I
  • 如何将图像从 np.uint16 转换为 np.uint8?

    我正在创建一个图像 image np empty shape height width 1 dtype np uint16 之后我将图像转换为 BGR 模型 image cv2 cvtColor image cv2 COLOR GRAY2B
  • OpenCV,捕获的视频比原始相机视频运行得更快!

    我正在使用 openCV 从相机捕获视频并将其存储到 avi 文件 问题是当我完成捕获并运行 avi 文件时 视频流看起来速度很快 这是代码 void main CvCapture capture cvCaptureFromCAM 0 in
  • 使用 cv2 在 python 中创建多通道零垫

    我想用 cv2 opencv 包装器在 python 中创建一个多通道 mat 对象 我在网上找到了一些例子 其中 c Mat zeros 被 numpy zeros 替换 这看起来不错 但似乎没有多通道类型适合 看代码 import cv
  • 使用 OpenCV VideoWriter 将 RTSP 流存储为视频文件

    我正在使用 OpenCV 开发一个 Python 模块 该模块连接到 RTSP 流以对视频执行一些预处理 主要是降低 fps 和分辨率 然后将其存储在文件系统中 但是 即使在尝试了几种编解码器 寻找类似的开发之后 我总是得到一个空的视频 我
  • 如何确定透视变换后的点在新图像平面中的位置?

    我使用 OpenCV Python Numpy 图像中有三个点 我知道这些点的确切位置 P1 P2 N1 我要将图像转换为另一个视图 例如 我将透视图转换为侧视图 如果这样做 我将无法获得图像平面中这三个点的确切位置 我应该以一种可以获得这
  • Android for OpenCV - 打开跟踪文件时出错,UnsatisfiedLinkError

    我对 Android 开发和 OpenCV 都是新手 我从 Android 下载了 OpenCV 库http sourceforge net projects opencvlibrary files opencv android http
  • 将yuv420p原始数据转换为opencv图像

    我有来自 rtmp 服务器的原始数据 像素格式为 yuv420p 我使用管道来读取数据 但我不知道如何将原始数据解码为图像 command ffmpeg command extend loglevel fatal i rtmp localh
  • 在 Python 中使用音频流 RTMP 通过管道和 OpenCV 到 FFmpeg

    我正在尝试使用音频流式传输 FFmpeg 我将在下面展示我的代码 导入模块 import subprocess as sp 创建变量 rtmpUrl rtmp a rtmp youtube com live2 key camera path
  • 使用 pygtk3 将 GUI 窗口添加到 python opencv2 程序

    我已经使用Python和Opencv2完成了一个程序 现在 我想向我的程序添加一个 GUI 窗口 我对 PyGtk3 有一些经验 因此 我修改了代码以采用 PyGtk3 但是 我遇到了错误 因此 我尝试了一个简单的程序来找出实际的错误 我的
  • 计数物体和更好的填充孔的方法

    我是 OpenCV 新手 正在尝试计算物体的数量在图像中 我在使用 MATLAB 图像处理工具箱之前已经完成了此操作 并在 OpenCV Android 中也采用了相同的方法 第一步是将图像转换为灰度 然后对其进行阈值计算 然后计算斑点的数
  • 如何使用 OpencV 从 Firebase 读取图像?

    有没有使用 OpenCV 从 Firebase 读取图像的想法 或者我必须先下载图片 然后从本地文件夹执行 cv imread 功能 有什么办法我可以使用cv imread link of picture from firebase 您可以
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 如何绘制每个分割对象的轮廓

    我应用分水岭分割来检测触摸对象 这样做效果很好 现在 我想绘制每个对象的轮廓 这样我就可以获得它们的长度 面积 矩等 但是分割结果中的对象仍然是触摸的 所以 我没能画出每一个的轮廓 如何绘制每个对象的轮廓 include
  • 线程“main”java.lang.UnsatisfiedLinkError中出现异常:java.library.path中没有opencv_java249

    我目前正在尝试在我的 32 位笔记本电脑上设置 OpenCV 但我不断收到一条令我困惑的错误消息 Exception in thread main java lang UnsatisfiedLinkError no opencv java2
  • 为什么opencv videowriter这么慢?

    你好 stackoverflow 社区 我有一个棘手的问题 我需要你的帮助来了解这里发生了什么 我的程序从视频采集卡 Blackmagic 捕获帧 到目前为止 它工作得很好 同时我用 opencv cv imshow 显示捕获的图像 它也工
  • OpenCV OpenNI 校准kinect

    我使用 home 通过 kinect 进行捕捉 capture retrieve depthMap CV CAP OPENNI DEPTH MAP capture retrieve bgrImage CV CAP OPENNI BGR IM

随机推荐

  • Deformable DETR源码解读

    文章目录 一 网络创新点 二 流程详解 part 1 deformable detr模块 part 2 deformable transformer模块 part3 Encoder模块 part 4 MSDeformAttn part5 D
  • Linux系统调试之gdbserver远程调试程序

    本篇讲解如何使用gdbserver对目标开发板上的程序进行远程调试 安装 GDBSERVER 首先在开发板上安装 gdbserver apt install gdbserver gdbserver 用法 gdbserver用法描述 Usag
  • redis概述-1

    视频链接 尚硅谷 Redis 6 入门到精通 超详细 教程 哔哩哔哩 bilibili 早期架构 随着web2 0 手机端和pc端的请求增加 应用服务器会有cpu及内存压力 数据服务器有IO压力 针对应用服务器 采用分布式 负载均衡的方式进
  • ILRuntime Unity热更新

    在新的项目中 使用到了ILRuntime的热更新方式 不同于XLua等 这种方式的热更新是由纯C 实现的 所以就不需要客户端懂Lua的代码 更详细的介绍可以看官方的文档 官方的介绍及文档为 http ourpalm github io IL
  • vcpkg安装和使用--学习入门

    前言 vcpkg是一个C 的包管理器 包管理器是专门管理一些代码库的 比如一些大佬们开源的一些NB的框架 我们可以用vcpkg将他们放到自己的项目中 然后就可以直接用了 我用的win10 vs2019 1 安装 1 先git clone下载
  • openwrt中计划任务的设置

    寝室的供网规则为周一到周五零点断网 六点开网 双休日通宵供网 故设置一套计划任务提高路由器使用效率 crontab命令常见于Unix和类Unix的操作系统之中 用于设置周期性被执行的指令 操作符号 在一个区域里填写多个数值的方法 逗号 分开
  • AcWing基础课题集汇总

    本篇博文是笔者归纳汇总的AcWing基础课题集 方便读者后期复盘巩固 PS 本篇文章只给出完整的算法实现 并没有讲解具体的算法思路 如果想看算法思路 可以阅读笔者往期写过的文章 或许会有 也可以移步AcWing官网看详情 本篇文章的特点 每
  • Qt应用开发(基础篇)——时间类 QDateTime、QDate、QTime

    一 前言 时间类QDateTime QDate QTime QTimeZone保存了Qt的时间 日期 时区信息 常用的时间类部件都会用到这些数据结构 常用概念有年 月 日 时 分 秒 毫秒和时区 时间和时区就关系到时间戳和UTC的概念 UT
  • Debian(Linux)系统Samba安装和配置

    samba安装 root用户下直接使用以下命令 apt get install samba 若是普通用户下使用以下命令 sudo apt get install samba samba配置 samba的配置文件在 etc samba 路径下
  • 1-2动态图

    文章目录 动态图 一 环境配置 二 基本用法 三 使用python的控制流 四 构建更加灵活的网络 控制流 五 构建更加灵活的网络 共享权重 The End 动态图 在这种模式下 每次执行一个运算 可以立即得到结果 而不是事先定义好网络结构
  • 基本数据类型的包装类

    本人之所以把包装类作为单独一篇博文来写 主要是因为这里知识比较冗杂 为了帮助大家比较好的理解深层次的东西而不是做一个搬砖的这里我有必要单开一篇博文来了解下 首先我们来分析一下基本数据类型和包装类 包装类是对象 拥有方法和字段 对象的调用都是
  • Python异常处理总结

    Python异常处理总结 这篇文章主要介绍了Python异常处理总结 需要的朋友可以参考下 本文较为详细的罗列了Python常见的异常处理 供大家参考 具体如下 1 抛出异常和自定义异常 Python用异常对象 exception obje
  • 《Java基础——制表符》

    Java基础 制表符 规则 若前面输出内容不为8的倍数 则通过空格补全 不足八位 补全八位 例一 不足八位 System out println 123456 t 空格补位 编译结果 123456 空格补位 例二 大于等于八位 System
  • 对高精度PWM(HRPWM)的理解

    传统PWM的精度 假定CPU工作频率为100MHz PWM模块的计数频率也一样 则计数周期为10ns 假设PWM的开关频率为1MHz 使用向上计数模式 那么 计数周期PRD等于100 此时 比较值只能在0 100里面选 占空比的精度只有1
  • mysql语法之update

    Update 语句 1 作用 Update 语句用于修改表中的数据 语法 UPDATE 表名称 SET 列名称 新值 WHERE 列名称 某值 1 建表语句 create table table1 idd varchar 10 val va
  • Python自学第十一天——Bug

    作为新手自学Python的第十一天 技术低微 希望可以通过这种方式督促自己学习 个人学习环境 python3 9 PyCharm 2021 3 2 Community Edition 本文仅做Bug基本知识梳理和简单解决方法简述 具体Bug
  • 解释二叉树深度和高度

    今天小伙伴在群里问到 面试官问这个问题 我第一印象 这不是一回事吗 去查了查 竟然还真有区别 所以在此记录一下 高度和深度是相反的表示 深度是从上到下数的 而高度是从下往上数 我们先来看看高度和深度的定义 某节点的深度是指从根节点到该节点的
  • vmware中虚拟机网络使用NAT模式,使外部主机可以连接

    将虚拟机网络类型配置成 注意 如果不知道什么原因无法访问网络 关闭所有虚拟机 点击还原默认设置 重置网络 vmware点击 编辑 gt 虚拟网络编辑器 点击NAT设置可以查看NAT网络的网关 点击DHCP设置 应该不需要 因为我用的是静态I
  • 【独家源码】ssm科普网站14o1y计算机毕业设计问题的解决方案与方法

    本项目包含程序 源码 数据库 LW 调试部署环境 文末可获取一份本项目的java源码和数据库参考 系统的选题背景和意义 选题背景 科学普及是推动科学知识传播和科学素养提升的重要途径 随着互联网的快速发展 科普网站成为了人们获取科学知识和信息
  • Mat使用笔记

    一 基本操作 1 1 创建 cv Mat初识和它的六种创建方法 cv Mat matDes nHEIGHT nWID CV 8UC1 cv Scalar 0 创建 row 高 col 宽 cv Mat matDes cv Mat zeros