C++ OpenCV制作黑客帝國風(fēng)格的照片
前不久,黑客帝國系列最新的 《矩陣重啟》 上映了。黑客帝國是早期科幻類型的翹楚。但是這次有點(diǎn)垮了。豆瓣評分不到6分。
小的時候,看到黑客帝國的那些照片,一串串?dāng)?shù)字從上而下, 感覺特別酷炫。 今天我們就來看看怎么制作類似的效果。
準(zhǔn)備工作
一張基努里維斯的照片
準(zhǔn)備好項目需要使用到的庫 opencv,在 CMakeLists.txt 里配置完成。
cmake_minimum_required(VERSION 3.17) project(opencv_demo) set(CMAKE_CXX_STANDARD 14) find_package(OpenCV 4 REQUIRED) include_directories( ? ? ? ? ${OPENCV_INCLUDE_DIRS} ) add_executable(opencv_demo main.cpp) target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES})
開始寫代碼
開始寫讀取文件的代碼
std::string path = "path/to/img"; cv::Mat img = cv::imread(path);
獲取到圖像的寬高
int height = img.rows; int width = img.cols; int cellHeight = 20, cellWidth = 20;
做一次圖片的縮放,然后進(jìn)行圖片的取色操作
cv::Mat img2 = img.clone(); cv::resize(img, img2, cv::Size((width/ cellWidth), (height / cellHeight)), 0.0, 0.0, cv::INTER_NEAREST);
新建一個圖片,用于放置 0 1 數(shù)字,需要注意的是,這里建立的新圖片需要和原圖的尺寸,顏色通道數(shù)等等都是相同的才行,否則后續(xù)合并圖片的時候,會有問題。
cv::Mat newImg = cv::Mat::zeros(height, width, CV_8UC3);
對新圖片進(jìn)行涂色添加文字處理
for (int i = 0; i < newHeight; ++i) { for (int j = 0; j < newWidth; ++j) { cv::Scalar color = img2.at<cv::Vec3b>(i, j); int b = color[0]; int g = color[1]; int r = color[2]; int k = (b + g + r) / 3; if (k < 128) { cv::putText(newImg, "1", cv::Point(j*cellWidth, i * cellHeight),cv::FONT_HERSHEY_COMPLEX_SMALL,0.7,cv::Scalar(0,g, 0)); } else { cv::putText(newImg, "0", cv::Point(j*cellWidth, i * cellHeight),cv::FONT_HERSHEY_COMPLEX_SMALL,0.7,cv::Scalar(0,g, 0)); } } }
到這一步我們的工作基本已經(jīng)完成了。 再進(jìn)行一次圖片合成,就OK了。
cv::addWeighted(img, 0.2, newImg , 0.8 , 0, img);
最終效果圖
完整代碼
#include <iostream> #include <opencv2/opencv.hpp> int main() { ? ? std::string path = "path/to/img"; ? ? cv::Mat img = cv::imread(path); ? ? ? ? int height = img.rows; ? ? int width = img.cols; ? ? int cellHeight = 20, cellWidth = 20; ? ? cv::Mat img2 = img.clone(); ? ? cv::resize(img, img2, cv::Size((width/ cellWidth), (height / cellHeight)), 0.0, 0.0, cv::INTER_NEAREST); ? ? int newWidth = img.cols; ? ? int newHeight = img.rows; ? ? cv::Mat newImg = cv::Mat::zeros(height, width, CV_8UC3); ? ?? ? ? for (int i = 0; i < newHeight; ++i) { ? ? ? ? for (int j = 0; j < newWidth; ++j) { ? ? ? ? ? ? cv::Scalar color = img2.at<cv::Vec3b>(i, j); ? ? ? ? ? ? int b = color[0]; ? ? ? ? ? ? int g = color[1]; ? ? ? ? ? ? int r = color[2]; ? ? ? ? ? ? int k = (b + g + r) / 3; ? ? ? ? ? ? if (k < 128) { ? ? ? ? ? ? ? ? cv::putText(newImg, "1", cv::Point(j*cellWidth, i * cellHeight),cv::FONT_HERSHEY_COMPLEX_SMALL,0.7,cv::Scalar(0,g, 0)); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? cv::putText(newImg, "0", cv::Point(j*cellWidth, i * cellHeight),cv::FONT_HERSHEY_COMPLEX_SMALL,0.7,cv::Scalar(0,g, 0)); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ?? ? ? cv::addWeighted(img, 0.2, newImg , 0.8 , 0, img); ? ? cv::imshow("def", img); ? ? cv::waitKey(0); }
總結(jié)
本文通過使用opencv 的取色, 上色, 圖片合并功能達(dá)到我們想要的效果。
到此這篇關(guān)于C++ OpenCV制作黑客帝國風(fēng)格的照片的文章就介紹到這了,更多相關(guān)OpenCV內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++報錯 XX does not name a type;
這篇文章主要給大家介紹了C++報錯 XX does not name a type;field `XX’ has incomplete type解決方案,文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下2023-08-08win32 api實(shí)現(xiàn)2048游戲示例
這篇文章主要介紹了win32 api實(shí)現(xiàn)2048游戲示例,需要的朋友可以參考下2014-05-05Qt數(shù)據(jù)庫應(yīng)用之超級自定義委托
Qt中需要用到自定義委托的情形很多,比如提供下拉框選擇,進(jìn)度條展示下載進(jìn)度啥的,默認(rèn)的單元格是沒有這些效果的,需要自己單獨(dú)用委托的形式來展示。本文將為大家介紹Qt中如何進(jìn)行超級自定義委托,需要的可以參考一下2022-03-03