他們製造着幻想與華鳥風月之美,製造着只有那裏纔有的誤會、和解與真實。
虛幻的東西反而帶給人們真實的五感,恐怕這便是二次元存在的意義吧。
如果硬要說的話,手機、電腦和程序倒也成了二次元的產物呢。
每天對着二維屏幕上的十幾行代碼傻傻發笑的不正是我們自己嗎?
因此,那些批判什麼二次元三次元,還總說別人活在自己的世界裏的人,倒是應該照照鏡子纔對。
更何況,你所看不到的是,在那些碎月與華麗的背後的造幻想之人的痛苦努力。
我們正視這些幻想,這也是對他人努力成果的一種認可與尊重,難道不是嗎?
好,今天利用QT和opengl和opencv帶大家進入幻想鄉,確切的說是把幻想鄉帶到現實中來。我們先上效果
#ifndef QSCARLETGLAUGMENTEDREALITY_H
#define QSCARLETGLAUGMENTEDREALITY_H
#include<QOpenGLWidget>
#include<QOpenGLFunctions>
#include<QOpenGLShaderProgram>
#include<QOpenGLBuffer>
#include<QGLWidget>
#include<QPoint>
#include<Eigen/Core>
#include<Eigen/Dense>
#include<QTimer>
#include<vector>
#include<QtOpenGL/QtOpenGL>
#include<opencv.hpp>
using namespace cv;
using namespace std;
//=================繪製增強現實類===============
#define MIN_LENGTH 35
#define IMAGE_WIDTH 640
#define IMAGE_HEIGHT 480
class QScarletGLAugmentedReality :public QGLWidget//,protected QOpenGLFunctions
{
//================需要注意的是,繼承方式的不同會導致代碼有很大差別
Q_OBJECT
public:
explicit QScarletGLAugmentedReality(QWidget* parent =0);
~QScarletGLAugmentedReality();//析構函數
protected:
//三個重載函數
void initializeGL();
void initWidget();
void paintGL();
void resizeGL(int ,int );
void loadGLTextures();//加載紋理
void mousePressEvent(QMouseEvent *);//鼠標單機事件三態
private:
//void start();//開始
//繪製增強現實
void imageProcess(Mat);
void initialize_AugmentReality();
void paint_AugmentReality();
void resize_AugmentReality(int ,int );
Mat frame;
VideoCapture cam,video;
vector<Point3f> Xworld;
vector<Point2f> Ximage;
GLfloat projection_matrix[16];
vector<GLdouble> rotMatrix;//某一個標記的變換矩陣
GLdouble rotMat[16];//爲了對應opengl函數格式定義的數組
//GLdouble *rotMatrix = new GLdouble(16);
vector<vector<GLdouble> > RotationMatrix;//將所有的變換矩陣保存同一渲染
Mat cameraMatrix = Mat(3,3,CV_64FC1,1);
Mat distCoeffs = Mat(1,4,CV_64FC1,1);
//opengl
QTimer clk;
//GLfloat m_x, m_y, m_z;
//GLfloat xx;
float WINDOW_SIZE;
//float Z_JUST;
//int WINDOW_SIZE;
GLuint m_texture[3];
GLuint texturImage;
GLuint texturFrame;
//鼠標響應
Mat warpMat;
Point2f dstRect[4];
Point2f srcRect[4];
char number;
Mat dobotPos = Mat(3, 1, CV_64FC1, Scalar(0, 0, 0));
Mat dobotTargetPos;
Point2f dobotFinalTargetPos;//歸一化後位置
private slots:
void updateWindow();
//void updateParams(int);
};
然後我們看一下類的實現。我就只粘貼核心代碼了,源碼之後會分享給各位。
void QScarletGLAugmentedReality::updateWindow()
{
//qDebug()<<"updateWindow";
//獲取攝像頭圖像並進行格式轉換
cam >> frame;
//cv::imshow("frame",frame);
//cv::waitKey();
cvtColor(frame, frame, CV_BGR2RGB);
for (char i = 0; i < 4; i++)
{
circle(frame, srcRect[i], 8, Scalar(255, 0, 0), -1, 8, 0);
}
circle(frame, Point(dobotPos.at<double>(0, 0), dobotPos.at<double>(1, 0)), 5, Scalar(0, 255, 255), -1, 8);
imageProcess(frame);//這個函數主要是對圖像處理,對二維碼進行識別。
QImage buf, tex;
//將Mat類型轉換成QImage
buf = QImage((const unsigned char*)frame.data, frame.cols, frame.rows, frame.cols * frame.channels(), QImage::Format_RGB888);
tex = QGLWidget::convertToGLFormat(buf);
glGenTextures(1, &texturFrame);//對應圖片的紋理定義
glBindTexture(GL_TEXTURE_2D, texturFrame);//進行紋理綁定
//紋理創建
glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
updateGL();
}
當然,這只是很少一部分代碼,但是它可以幫我們理清思路。首先利用opencv攝像頭讀取影像,轉化爲opengl所用的色彩格式,然後進行圖像中的二維碼識別,進行座標轉換,最後用opengl進行繪製。愛我次奧不得不說原文的博主真是忒tm強悍了。順帶說一句,二維碼長成這個樣子。事實上,opencv3.2的contrib模塊中有對這種二維碼進行識別的模塊。也不是很複雜,主要是結合sovePnp函數進行位姿估計。
附上h文件和cpp文件的源碼連接:
http://download.csdn.net/download/qq_30547073/9967390
沒錯,我想說的是,對某件事物的執着一定可以帶給你力量,它可以讓你獲得忍受一切痛苦與屈辱的能力。
總有一天,你所堅持的事物會像金子一樣閃閃發光。
那時你會被稱爲神明,因爲你做到了其他人永遠做不到的事情。