在ubuntu系统上,用KDevelop开发环境写的代码,所以有main.cpp和CMakeLists.txt两个文件。
没有KDevelop也可以,直接mkdir build && cd build && cmake … && make
main.cpp
#include <iostream>
#include <string>
#include <math.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#define pi 3.1415926
// /usr/local/lib
// /usr/local/include/opencv2
// /usr/local/share/licenses
// /usr/local/share
// /usr/local/bin/opencv_version
using namespace std;
template<typename T, typename ... Ts>
void print(T out)
{
cout << out << endl;
}
double sin_(int m)
{
return sin(m*pi/180);
}
double cos_(int m)
{
return cos(m*pi/180);
}
//把所有度数统一到 -180 to 180
int mod(int degree)
{
if(degree>=0)
{
if(degree%360<180) return degree%360;
else if(degree%360>180) return degree%360-360;
}
else if(degree<0)
{
if(degree>=-180) return degree;
else
{
while(1)
{
degree+=360;
if(degree>-180) break;
}
return degree;
}
}
}
void imshow_(cv::Mat img)
{
cv::imshow("0",img);
}
//把src放到dst的中间,这个函数没用上,留着备用不删
void center_paste(cv::Mat &src, cv::Mat &dst)
{
int src_w = src.cols;
int src_h = src.rows;
int dst_w = dst.cols;
int dst_h = dst.rows;
cv::Rect rect = cv::Rect((dst_w-src_w)/2, (dst_h-src_h)/2, src_w, src_h); //x,y,w,h
src.copyTo(dst(rect));
}
int main(int argc, char **argv)
{
define the src img
cv::Mat img;
img = cv::imread("../3.jpg");
int rows = img.rows;
int cols = img.cols;
cout << "src size = " << cols << ' ' << rows << endl;
imshow_(img);
cv::waitKey(0);
define the dst img
int theta = -30;
int rows_n,cols_n,theta_mod,theta_abs;
theta_mod = mod(theta); // -180 ~ 180
cout << "real degree = " << theta_mod << endl;
if(theta_mod<90 && theta_mod>-90)
{
theta_abs = abs(theta_mod);
}
else if(theta_mod>=90)
{
theta_abs = 180-theta_mod;
}
else if(theta_mod<=-90)
{
theta_abs = 180+theta_mod;
}
rows_n = cols*sin_(theta_abs)+rows*cos_(theta_abs);
cols_n = cols*cos_(theta_abs)+rows*sin_(theta_abs);
cv::Mat img_n(rows_n, cols_n, CV_8UC3, cv::Scalar(0,0,0));
cout << "dst size = " << cols_n << ' ' << rows_n << endl;
//start to roll
//center point of the dst img
int center_x = img_n.cols/2;
int center_y = img_n.rows/2;
for(int x=0;x<cols;x++)
{
for(int y=0;y<rows;y++)
{
//索引到欧式坐标转换,旋转
int x_n = (x-cols/2)*cos_(theta) - (-y+rows/2)*sin_(theta);
int y_n = (-y+rows/2)*cos_(theta) + (x-cols/2)*sin_(theta);
//cout << x << ' ' << y << ' ' << (x-cols/2) << ' ' << (y-rows/2) << ' ' << x_n << ' ' << y_n << endl;
//img.at<cv::Vec3b>(y row,x col);
img_n.at<cv::Vec3b>(center_y-y_n, center_x+x_n) = img.at<cv::Vec3b>(y,x);
}
imshow_(img_n);
cv::waitKey(1);
}
//双线性插值
for(int i=1;i<rows_n-1;i++)
{
for(int j=1;j<cols_n;j++)
{
if(img_n.at<cv::Vec3b>(i,j)[0]==0 && img_n.at<cv::Vec3b>(i,j)[1]==0 && img_n.at<cv::Vec3b>(i,j)[2]==0)
{
img_n.at<cv::Vec3b>(i,j)[0] = (img_n.at<cv::Vec3b>(i-1,j-1)[0]+img_n.at<cv::Vec3b>(i+1,j+1)[0])/2;
img_n.at<cv::Vec3b>(i,j)[1] = (img_n.at<cv::Vec3b>(i-1,j-1)[1]+img_n.at<cv::Vec3b>(i+1,j+1)[1])/2;
img_n.at<cv::Vec3b>(i,j)[2] = (img_n.at<cv::Vec3b>(i-1,j-1)[2]+img_n.at<cv::Vec3b>(i+1,j+1)[2])/2;
// img_n.at<cv::Vec3b>(i,j) = img_n.at<cv::Vec3b>(i+1,j+1);
}
}
}
//cv::imwrite("roll.jpg",img_n);
imshow_(img_n);
cv::waitKey(0);
return 0;
}
CMakeLists.txt
复制的时候把注释删掉,CMake好像不能有注释
cmake_minimum_required(VERSION 3.0)
project(cv)
# using C++11
set( CMAKE_CXX_FLAGS "-std=c++11 ")
#
//find_package会自动生成OpenCV_INCLUDE_DIRS和OpenCV_LIBS
//下面直接调用就行
find_package(OpenCV REQUIRED)
#
include_directories( ${OpenCV_INCLUDE_DIRS})
#
add_executable(cv main.cpp)
#
target_link_libraries( cv ${OpenCV_LIBS})