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使用笔记 的相关文章

  • VideoCapture 未检测到 uEye 摄像头

    我的 uEye 相机遇到了一个问题 使用我的笔记本电脑摄像头 id 0 或 USB 上的网络摄像头 id 1 此行完美运行 TheVideoCapturer open 1 TheVideoCapturer 属于 VideoCapture 类
  • GrabCut - bgdModel 和 fgdModel 为空 - 断言错误

    我正在尝试使用 OpenCV2 1 C 中的 GrabCut 算法进行图像分割 这是我的代码 Mat rgbWorkImage imread argv 1 Mat mask mask Scalar 0 Mat bgdModel fgdMod
  • 从凸点获取角点

    我编写了算法来提取图像中显示的点 它们形成凸形 我知道它们的顺序 如何从这些点中提取角点 顶部 3 个和底部 3 个 我正在使用opencv 如果你已经有了物体的凸包 并且该包包含角点 那么你需要做的就是简化包直到它只有 6 个点 有很多方
  • 使用opencv+picamera流IO用树莓派捕获视频

    我使用 Raspberry 来简单地显示一个视频 目前仅此 为此 我必须使用 opencv cv2 我尝试了很多解决方案 但现在我想使用 Picamera 库捕获视频 我将向您展示我的代码 import io import time imp
  • 使用 openCV 对图像中的子图像进行通用检测

    免责声明 我是计算机视觉菜鸟 我看过很多关于如何在较大图像中查找特定子图像的堆栈溢出帖子 我的用例有点不同 因为我不希望它是具体的 而且我不确定如何做到这一点 如果可能的话 但我感觉应该如此 我有大量图像数据集 有时 其中一些图像是数据集的
  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 寻找两个框架之间的变换

    我有来自视频源的两个连续帧 并且我使用 FAST 算法检测这两个帧的关键点 我使用平方差之和法 SSD 来匹配关键点 所以基本上我已经匹配了两个框架之间的关键点 现在我想根据匹配的关键点集计算两个帧之间的仿射变换 缩放 旋转 平移 我知道如
  • 每当使用 import cv2 时 OpenCV 都会出错

    我在终端上使用 pip3 install opencv contrib python 安装了 cv2 并且它工作了 但是每当我尝试导入 cv2 或运行导入了 cv2 的 vscode 文件时 在 python IDLE 上它都会说 Trac
  • 如何在不使用OpenCV Python中的split函数的情况下获取图像的单一颜色通道?

    我想强调一下用于实时手势识别的手 我观察到 使用 cv2 imsplit 函数 手的图像对于不同的颜色通道会以不同的方式突出显示 但这种分割功能在时间上是非常昂贵的 我无法使用 Numpy 索引执行相同的功能 如官方网站 https doc
  • OpenCV/FFMpeg 图像捕获问题

    我正在尝试从网络摄像机实时捕获图像 该流在 VLC 中运行得很好 但 OpenCV 的cvQueryFrame 似乎使传入的图像变得混乱和损坏 以至于无法识别 同样 从文件捕获可以正常工作 但实时流则不行 为了以防万一 我使用了 rtsp
  • python求边数

    我使用下面的代码来查找图像中的边数 但它没有给出适当的结果 导入CV2 image cv2 imread sheet jpg gray cv2 cvtColor image cv2 COLOR BGR2GRAY thresh cv2 thr
  • OpenCV C++ 多线程

    我在 4 个不同的 Mat 对象上调用了 4x 这个 opencv 图像处理函数 void processBinary Mat binaryMat image processing 我想要对其进行多线程处理 以便所有 4 个方法调用同时完成
  • 如何从图像中提取 RGB 并仅将 RG 绘制为图形? R 代表 X,G 代表 Y

    我正在尝试从图像中提取 RGB 分量并使用 matplotlib 绘制 3D RGB 直方图 但我不知道该怎么做 这是我当前的代码 import cv2 import numpy as np from scipy import ndimag
  • 找不到 tbb.dll

    我在 opencv 2 3 中使用 cvCanny 函数 它编译得很好 但在执行时出现错误 提示 tbb dll 未找到 这个dll有什么用处 在哪里可以找到这个 thanks 它是英特尔的一部分线程构建块 http threadingbu
  • 将曲线图案与图像边缘匹配

    我有一个要搜索沿其边缘的曲线的目标图像和一个包含该曲线的模板图像 我需要实现的是在目标图像中找到模板图像中的曲线的最佳匹配 并根据分数来判断是否匹配 这还包括曲线的旋转和大小调整 目标图像可以是 Canny Edge 检测器的输出 如果这能
  • 在Opencv Python中将RGB图像转换为YUV和YCbCr颜色空间图像

    谁能帮我使用 opencv Python 将 RGB 颜色空间图像转换为 YUV 颜色空间图像和 YCbCr 颜色空间图像 Use cv2 cvtColor src code 要转换颜色空间 代码以COLOR 您可以使用它来查找颜色代码 i
  • 使用 openCV 检测 ROI

    我正在做一项工作 我必须找到感兴趣的区域 ROI 然后对图像执行阈值 由于我不是计算机领域的 所以我遇到了一些困难 我开始尝试通过以下代码找到投资回报率 code string filename 2011 06 11 09 3A12 3A1
  • 将浮点数组图像转换为可用于 opencv 的格式

    我想知道是否有一种简单的方法可以将浮点数组图像转换为 iplimage 可以用opencv来处理 当然 我可以创建一个具有相同大小的空 iplimage 然后将浮点数组图像中的每个像素复制到空 iplimage 但是是否有更优雅的解决方案
  • OpenCV - 我需要将彩色图像插入黑白图像并且

    我用以下代码将黑白图像插入彩色图像 没问题 face grey cv cvtColor face cv COLOR RGB2GRAY for row in range 0 face grey shape 0 for column in ra

随机推荐

  • 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