opencv实现图像的缩放
2017-06-02 23:26
387 查看
图像的缩放是指将图像的尺寸变小或者变大的过程,也就是减少或者增加原图像数据的像素个数。图像缩放会在一定程度上面丢失图像的信息,因此需要考虑适宜的方法进行操作。如果数字图像中像素坐标为非负整数,图像缩放过程很可能回事的某些坐标为浮点数,因此需要用到图像插值方法、
1.基于等间隔提取图像缩放
等间隔图像缩放时通过对源图像进行均匀采样来完成的。对于源图像数据f(x,y),其分辨率为M*N,如果将其分辨率改成m*n,对于等间隔采样而言,其宽度缩放因子就是M/m,高度缩放因子就是N/n。如果宽度和高度缩放成都相等的话,那就代表源图像数据等比例缩放。如果不等,那就会照成图形扭曲现象。
2.基于区域子快提取图像缩放
区域子快提取图像缩放时通过对源图像进行区域子快划分。然后提取子块中的像素值作为采样像素已构成新的图像来实现。提取子快图像值常用的方法有计算子快像素的中值与计算子快的均值。对源图像进行区域划分同样也有很多种方法,常用的方法是根据缩放因子等比例的提取子快与自适应因子提取子快。
代码如下:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace std;
//基于等间隔提取图像缩放
cv::Mat imageReduction1(cv::Mat &srcImage, float kx, float ky)
{
//获取输出图像分辨率
int nRows = cvRound(srcImage.rows * kx);
int nCols = cvRound(srcImage.cols * ky);
cv::Mat resultImage(nRows, nCols, srcImage.type());
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
//根据水平因子计算坐标,static_cast用于类型转换
int x = static_cast<int>((i + 1) / kx + 0.5) - 1;
//根据垂直因子计算坐标
int y = static_cast<int>((j + 1) / ky + 0.5) - 1;
resultImage.at<cv::Vec3b>(i, j) = srcImage.at<cv::Vec3b>(x, y);
}
}
return resultImage;
}
cv::Vec3b areaAverage(const cv::Mat &srcImage, cv::Point_<int> leftPoint, cv::Point_<int> rightPoint)
{
int temp1 = 0, temp2 = 0, temp3 = 0;
//计算子快区域的像素点个数
int nPix = (rightPoint.x - leftPoint.x + 1) * (rightPoint.y - leftPoint.y + 1);
//对区域子快各个通道对像素值求和
for (int i = leftPoint.x; i <= rightPoint.x; i++)
{
for (int j = leftPoint.y; j <= rightPoint.y; j++)
{
temp1 += srcImage.at<cv::Vec3b>(i, j)[0];
temp2 += srcImage.at<cv::Vec3b>(i, j)[1];
temp3 += srcImage.at<cv::Vec3b>(i, j)[2];
}
}
//对每个通道求平均值
cv::Vec3b vecTemp;
vecTemp[0] = temp1 / nPix;
vecTemp[1] = temp2 / nPix;
vecTemp[2] = temp3 / nPix;
return vecTemp;
}
cv::Mat imageReduction2(const cv::Mat &srcImage, double kx, double ky)
{
//获取输出图像分辨率
int nRows = cvRound(srcImage.rows * kx);
int nCols = cvRound(srcImage.cols * ky);
cv::Mat resultImage(nRows, nCols, srcImage.type());
//区域子快的左上角行列坐标
int leftRowCoordinate = 0;
int leftColCoordinate = 0;
for (int i = 0; i < nRows; ++i)
{
//根据水平因子计算坐标
int x = static_cast<int>((i + 1) / kx + 0.5) - 1;
for (int j = 0; j < nCols; ++j)
{
//根据垂直因子计算
int y = static_cast<int>((j + 1) / ky + 0.5) - 1;
//求区域子快的均值
resultImage.at<cv::Vec3b>(i, j) = areaAverage(srcImage, cv::Point_<int>(leftRowCoordinate, leftColCoordinate), cv::Point_<int>(x, y));
//更新下子快左上角的列坐标,行坐标不变
leftColCoordinate = y + 1;
}
leftColCoordinate = 0;
leftRowCoordinate = x + 1;
}
return resultImage;
}
int main()
{
cv::Mat srcImage = cv::imread("C:\\Users\\LP\\Desktop\\C++\\ConsoleApplication4\\ConsoleApplication4\\1.jpg");
if(srcImage.empty())
{
return -1;
}
cv::imshow("原图像", srcImage);
cv::Mat resultImage1 = imageReduction1(srcImage, 0.5, 0.5);
cv::imshow("res1", resultImage1);
cv::Mat resultImage2 = imageReduction2(srcImage, 0.5, 0.5);
cv::imshow("res2", resultImage2);
cv::waitKey(0);
return 0;
}
1.基于等间隔提取图像缩放
等间隔图像缩放时通过对源图像进行均匀采样来完成的。对于源图像数据f(x,y),其分辨率为M*N,如果将其分辨率改成m*n,对于等间隔采样而言,其宽度缩放因子就是M/m,高度缩放因子就是N/n。如果宽度和高度缩放成都相等的话,那就代表源图像数据等比例缩放。如果不等,那就会照成图形扭曲现象。
2.基于区域子快提取图像缩放
区域子快提取图像缩放时通过对源图像进行区域子快划分。然后提取子块中的像素值作为采样像素已构成新的图像来实现。提取子快图像值常用的方法有计算子快像素的中值与计算子快的均值。对源图像进行区域划分同样也有很多种方法,常用的方法是根据缩放因子等比例的提取子快与自适应因子提取子快。
代码如下:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace std;
//基于等间隔提取图像缩放
cv::Mat imageReduction1(cv::Mat &srcImage, float kx, float ky)
{
//获取输出图像分辨率
int nRows = cvRound(srcImage.rows * kx);
int nCols = cvRound(srcImage.cols * ky);
cv::Mat resultImage(nRows, nCols, srcImage.type());
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
//根据水平因子计算坐标,static_cast用于类型转换
int x = static_cast<int>((i + 1) / kx + 0.5) - 1;
//根据垂直因子计算坐标
int y = static_cast<int>((j + 1) / ky + 0.5) - 1;
resultImage.at<cv::Vec3b>(i, j) = srcImage.at<cv::Vec3b>(x, y);
}
}
return resultImage;
}
cv::Vec3b areaAverage(const cv::Mat &srcImage, cv::Point_<int> leftPoint, cv::Point_<int> rightPoint)
{
int temp1 = 0, temp2 = 0, temp3 = 0;
//计算子快区域的像素点个数
int nPix = (rightPoint.x - leftPoint.x + 1) * (rightPoint.y - leftPoint.y + 1);
//对区域子快各个通道对像素值求和
for (int i = leftPoint.x; i <= rightPoint.x; i++)
{
for (int j = leftPoint.y; j <= rightPoint.y; j++)
{
temp1 += srcImage.at<cv::Vec3b>(i, j)[0];
temp2 += srcImage.at<cv::Vec3b>(i, j)[1];
temp3 += srcImage.at<cv::Vec3b>(i, j)[2];
}
}
//对每个通道求平均值
cv::Vec3b vecTemp;
vecTemp[0] = temp1 / nPix;
vecTemp[1] = temp2 / nPix;
vecTemp[2] = temp3 / nPix;
return vecTemp;
}
cv::Mat imageReduction2(const cv::Mat &srcImage, double kx, double ky)
{
//获取输出图像分辨率
int nRows = cvRound(srcImage.rows * kx);
int nCols = cvRound(srcImage.cols * ky);
cv::Mat resultImage(nRows, nCols, srcImage.type());
//区域子快的左上角行列坐标
int leftRowCoordinate = 0;
int leftColCoordinate = 0;
for (int i = 0; i < nRows; ++i)
{
//根据水平因子计算坐标
int x = static_cast<int>((i + 1) / kx + 0.5) - 1;
for (int j = 0; j < nCols; ++j)
{
//根据垂直因子计算
int y = static_cast<int>((j + 1) / ky + 0.5) - 1;
//求区域子快的均值
resultImage.at<cv::Vec3b>(i, j) = areaAverage(srcImage, cv::Point_<int>(leftRowCoordinate, leftColCoordinate), cv::Point_<int>(x, y));
//更新下子快左上角的列坐标,行坐标不变
leftColCoordinate = y + 1;
}
leftColCoordinate = 0;
leftRowCoordinate = x + 1;
}
return resultImage;
}
int main()
{
cv::Mat srcImage = cv::imread("C:\\Users\\LP\\Desktop\\C++\\ConsoleApplication4\\ConsoleApplication4\\1.jpg");
if(srcImage.empty())
{
return -1;
}
cv::imshow("原图像", srcImage);
cv::Mat resultImage1 = imageReduction1(srcImage, 0.5, 0.5);
cv::imshow("res1", resultImage1);
cv::Mat resultImage2 = imageReduction2(srcImage, 0.5, 0.5);
cv::imshow("res2", resultImage2);
cv::waitKey(0);
return 0;
}
相关文章推荐
- opencv缩放图像的实现
- Android Jni 利用OpenCV 实现图像尺寸缩放(三)
- 用OpenCV的resize函数实现图像的缩放
- Android Jni 利用OpenCV 实现图像尺寸缩放(一)
- opencv实现图像的剪切和缩放
- Android Jni 利用OpenCV 实现图像尺寸缩放(二)
- opencv3 图像处理(一)图像缩放( python与c++ 实现)
- [转]opencv3 图像处理 之 图像缩放( python与c++实现 )
- 数字图像的缩放及opencv中的实现
- opencv实现图像缩放及canny边缘处理
- OpenCV实现图像缩放
- opencv实现图像缩放
- matlab实现图像的平移、旋转、缩放
- 使用opencv实现图像局部放大功能
- Opencv2.1中的图像切分grabcut实现
- 基于CUDA和OpenCV实现的图像GAMMA变换
- OpenCV学习笔记(16)双目测距与三维重建的OpenCV实现问题集锦(一)图像获取与单目定标
- 用线性插值算法实现图像缩放
- [Android]android.graphics.Camera实现图像的旋转、缩放,配合Matrix实现图像的倾斜
- OPENCV下针对IplImage实现图像增强处理