opencv Mat 使用时的注意事项

本文总结了在使用OpenCV处理图像时遇到的问题,包括imread()读取图像可能出现的3通道问题以及normalize()函数对单通道图像的要求。建议新手注意imread()读取灰度图像时使用特定参数,并理解normalize()对输入矩阵通道的要求。
摘要由CSDN通过智能技术生成

下面的small tips 是我在做毕设时处理图片遇到的一些问题,先如今都已经找到了解决的方法,适合于opencv的新手看一看。


1. imread() 小陷阱

imread('img.jpg');

这条语句读进来的是3通道,无论img.jpg是单通道的图像还是3通道的图像,所以输入图像如果是灰度图像,为了不出错,可以使用

imread("img.jpg",-1);

2.normalize() 小陷阱

要注意它的输入矩阵必须是单通道的,具体可见下方红色部分。

<span style="font-size:14px;">
//

//#include "stdafx.h"

#include <iostream>     
#include "opencv2/core/core.hpp"     
#include "opencv2/features2d/features2d.hpp"     
#include "opencv2/highgui/highgui.hpp"     
#include <iostream>  
#include <fstream>
#include <vector>
#include <opencv2/legacy/legacy.hpp>

using namespace cv;    
using namespace std;    
int main()    
{    
      Mat img_1 = imread("lena_color.bmp"); 
	//定义变量
	double min1,min2,min3,max1,max2,max3;
	ofstream Channel1,Channel2,Channel3;
	ofstream Channel1n,Channel2n,Channel3n;

	//<span style="background-color: rgb(255, 102, 102);">打开存储所需要的数据的文本,如果没有,则新建</span>
	Channel1.open("Channel1PixelValue.txt");
	Channel2.open("Channel2PixelValue.txt");
	Channel3.open("Channel3PixelValue.txt");
	Channel1n.open("Channel1PixelValueNormed.txt");
	Channel2n.open("Channel2PixelValueNormed.txt");
	Channel3n.open("Channel3PixelValueNormed.txt");

	vector<Mat> channels;//用来存放三个通道的像素值,channels 有三个元素,每个元素代表一个通道,一个通道一个就是一个Mat

	Mat norm1,norm2,norm3;
	//分离出三个通道并存储
        split(img_1,channels); 
	Channel1<<channels.at(0);
	Channel2<<channels.at(1);
	Channel3<<channels.at(2);

	//找到三个通道里的最大最小值,确定归一化函数的第二个和第三个参数
	minMaxIdx(channels.at(0), &min1, &max1);
	minMaxIdx(channels.at(1), &min2, &max2);
	minMaxIdx(channels.at(2), &min3, &max3);

	//<span style="background-color: rgb(255, 102, 102);">如果要用normalize函数得到0和1之间的小数像素值,输入矩阵不能是int类型,这里转换为float类型已经足够</span>
	Mat_<float> temp1,temp2,temp3;
    channels.at(0).convertTo(temp1, CV_32F);
    channels.at(1).convertTo(temp2, CV_32F);
    channels.at(2).convertTo(temp3, CV_32F);
	
	//归一化三个通道的值
	normalize(temp1,norm1,1.0,0.0,CV_MINMAX);
	normalize(temp2,norm2,1.0,0.0,CV_MINMAX);
	normalize(temp3,norm3,1.0,0.0,CV_MINMAX);

	//储存归一化后的三个通道的值
	Channel1n<<norm1;
	Channel2n<<norm2;
	Channel3n<<norm3;
	
	//以图像的形式存储起来三个通道的值
        imwrite("channel1.jpg",channels.at(0));
	imwrite("channel2.jpg",channels.at(1));
	imwrite("channel3.jpg",channels.at(2));
	//
	//
    ORB orb;    
    vector<KeyPoint> keyPoints_1;
    Mat descriptors_1;
    orb(img_1, Mat(), keyPoints_1, descriptors_1);    
    
    // 获得当前的坐标
	cv::Mat output;
	cv::drawKeypoints(img_1,keyPoints_1,output);
	cv::imshow("imgpath",output); 
	waitKey(0);
        return 0;
}   </span>
3.Mat.at() 小陷阱

在今天我对于一个Mat src 进行at(0,0)取像素值操作,src.at(0,0)这样写是错误的。应该要写成src.at<double>(0,0).

由于我对泛型理解太浅所以出现了这种错误。


以后遇到再补充好啦!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值