opencv resize c++实现
主要用到插值。
首先是对列方向插值,然后对行方向插值。参考了yolov3中resize图片源码
#include <iostream>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
unsigned char getval(unsigned char* ptr, int cols, int height, int width)
{
return ptr[height*cols + width];
}
void setval(unsigned char* ptr, int cols, int height, int width, unsigned char pixel)
{
ptr[height*cols + width] = pixel;
}
unsigned char* resize(unsigned char* ptr, int rows, int cols, int h, int w)
{
unsigned char* part = (unsigned char*)malloc(sizeof(unsigned char)*w*rows);
unsigned char* dst = (unsigned char*)malloc(sizeof(unsigned char)*w*h);
float wscale = cols / (float)w;
float hscale = rows / (float)h;
unsigned char val;
for (int r = 0; r < rows; r++)
for (int c = 0; c < w; c++)
{
if (c == 0 || c == w - 1)
{
val = getval(ptr, cols, r, c);
}
else
{
float x1 = c * wscale;
int x2 = (int)x1;
float diffx = x1 - x2;
val = (1 - diffx)*getval(ptr, cols, r, x2) + diffx*getval(ptr, cols, r, x2 + 1);
}
setval(part, w, r, c, val);
}
for (int r = 0; r < h; r++)
{
float y1 = r * hscale;
int y2 = (int)y1;
float diffy = y1 - y2;
for (int c = 0; c < w; c++)
{
if (r == 0 || r == h - 1)
{
val = getval(part, w, r, c);
}
else
{
val = (1 - diffy)*getval(part, w, y2, c) + diffy * getval(part, w, y2+1, c);
}
setval(dst, w, r, c, val);
}
}
free(part);
return dst;
}
int main(void)
{
cv::Mat src = cv::imread("apple.jpg");
cv::imshow("apple.jpg", src);
cv::cvtColor(src, src, CV_BGR2GRAY);
double t1 = cv::getTickCount();
unsigned char* resizebf = resize(src.data, src.rows, src.cols, 416, 416);
double t2 = cv::getTickCount() - t1;
printf("resize cost time: %.3fms\n", t2 * 1000 / cv::getTickFrequency());
cv::Mat dst;
t1 = cv::getTickCount();
cv::resize(src, dst, cv::Size(416, 416));
t2 = cv::getTickCount() - t1;
printf("opencv resize cost time: %.3fms\n", t2 * 1000 / cv::getTickFrequency());
cv::Mat save(416, 416, CV_8UC1, resizebf);
cv::imshow("test.jpg", save);
cv::waitKey(0);
free(resizebf);
return 0;
}
对比两个resize的时间,上位机打印结果