# 怎么用C++ OpenCV實現像素畫

*圖1:使用OpenCV生成的像素畫效果*
## 一、像素畫概述
像素畫(Pixel Art)是一種以單個像素為基本單位進行創作的數字藝術形式,最早源于8-bit和16-bit時代的電子游戲。在現代圖像處理中,我們可以通過算法將普通照片轉換為像素畫風格,這種技術廣泛應用于游戲開發、數字藝術創作等領域。
### 像素畫的核心特征:
1. **低分辨率**:通常使用較小的畫布尺寸
2. **有限的調色板**:使用少量顏色表現圖像
3. **清晰的像素邊緣**:沒有抗鋸齒處理
4. **明確的輪廓**:強調物體的形狀特征
## 二、OpenCV環境準備
### 1. 安裝OpenCV
```bash
# Ubuntu安裝命令
sudo apt-get install libopencv-dev
# Windows可通過vcpkg安裝
vcpkg install opencv
cmake_minimum_required(VERSION 3.10)
project(PixelArtConverter)
find_package(OpenCV REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main ${OpenCV_LIBS})
Mat createPixelArt(const Mat& input, int pixelSize = 10, int colorLevels = 8) {
// 檢查輸入有效性
CV_Assert(!input.empty());
CV_Assert(pixelSize > 0);
// 計算降采樣后的尺寸
Size smallSize(input.cols/pixelSize, input.rows/pixelSize);
// 降采樣處理
Mat smallImg;
resize(input, smallImg, smallSize, 0, 0, INTER_NEAREST);
// 顏色量化
Mat pixelArt;
colorQuantization(smallImg, pixelArt, colorLevels);
// 放大回原尺寸
Mat output;
resize(pixelArt, output, input.size(), 0, 0, INTER_NEAREST);
return output;
}
void colorQuantization(Mat& input, Mat& output, int levels) {
CV_Assert(input.type() == CV_8UC3);
// 轉換到Lab顏色空間(更好的顏色聚類效果)
Mat labImg;
cvtColor(input, labImg, COLOR_BGR2Lab);
// 準備K-means聚類數據
Mat samples(input.rows * input.cols, 3, CV_32F);
for (int i = 0; i < labImg.rows; i++) {
for (int j = 0; j < labImg.cols; j++) {
for (int k = 0; k < 3; k++) {
samples.at<float>(i * labImg.cols + j, k) = labImg.at<Vec3b>(i, j)[k];
}
}
}
// 執行K-means聚類
Mat labels, centers;
kmeans(samples, levels, labels,
TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 1.0),
3, KMEANS_PP_CENTERS, centers);
// 重建圖像
output = Mat(input.size(), input.type());
for (int i = 0; i < labImg.rows; i++) {
for (int j = 0; j < labImg.cols; j++) {
int clusterIdx = labels.at<int>(i * labImg.cols + j, 0);
output.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(centers.at<float>(clusterIdx, 0));
output.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(centers.at<float>(clusterIdx, 1));
output.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(centers.at<float>(clusterIdx, 2));
}
}
cvtColor(output, output, COLOR_Lab2BGR);
}
void enhanceEdges(Mat& input, Mat& output) {
Mat gray, edges;
cvtColor(input, gray, COLOR_BGR2GRAY);
Canny(gray, edges, 50, 150);
// 將邊緣轉為黑色
Mat invertedEdges = 255 - edges;
cvtColor(invertedEdges, invertedEdges, COLOR_GRAY2BGR);
// 混合原始圖像和邊緣
output = input & invertedEdges;
}
#include <opencv2/opencv.hpp>
using namespace cv;
// 前面提到的函數實現...
int main(int argc, char** argv) {
// 讀取輸入圖像
Mat input = imread("input.jpg");
if (input.empty()) {
std::cerr << "無法加載圖像!" << std::endl;
return -1;
}
// 創建像素畫
int pixelSize = 16; // 像素塊大小
int colorLevels = 8; // 顏色級別
Mat pixelArt = createPixelArt(input, pixelSize, colorLevels);
// 可選:增強邊緣
enhanceEdges(pixelArt, pixelArt);
// 顯示結果
imshow("原始圖像", input);
imshow("像素畫", pixelArt);
waitKey(0);
// 保存結果
imwrite("pixel_art_output.png", pixelArt);
return 0;
}
像素尺寸 | 效果特點 | 適用場景 |
---|---|---|
4-8px | 高度抽象 | 小圖標制作 |
10-16px | 平衡效果 | 游戲素材 |
20-32px | 保留細節 | 大型藝術作品 |
// 對大圖像先進行適當縮小
if (input.rows > 1000 || input.cols > 1000) {
resize(input, input, Size(), 0.5, 0.5);
}
void addGridLines(Mat& img, int pixelSize, const Scalar& color = Scalar(0,0,0)) {
for (int i = 0; i < img.rows; i += pixelSize) {
line(img, Point(0, i), Point(img.cols, i), color);
}
for (int j = 0; j < img.cols; j += pixelSize) {
line(img, Point(j, 0), Point(j, img.rows), color);
}
}
Mat generatePalettePreview(const Mat& centers) {
int swatchSize = 50;
Mat palette(swatchSize, centers.rows * swatchSize, CV_8UC3);
for (int i = 0; i < centers.rows; i++) {
Rect roi(i * swatchSize, 0, swatchSize, swatchSize);
Mat colorSwatch = palette(roi);
colorSwatch = Scalar(
centers.at<float>(i, 0),
centers.at<float>(i, 1),
centers.at<float>(i, 2));
}
return palette;
}
圖像出現色帶(Banding)
void addNoise(Mat& img, float strength = 0.01f) {
Mat noise(img.size(), img.type());
randn(noise, 0, 255 * strength);
img += noise;
}
邊緣鋸齒過于明顯
GaussianBlur(input, input, Size(3,3), 0.5);
處理速度慢
本文詳細介紹了使用C++和OpenCV實現像素畫效果的全過程。關鍵點包括: 1. 通過降采樣和顏色量化實現基本效果 2. 使用K-means算法進行智能顏色縮減 3. 多種增強效果的可選方案
通過調整參數和添加個性化處理,開發者可以創造出各種風格的像素畫效果。完整代碼已提供在GitHub倉庫(示例鏈接)。
提示:在實際應用中,建議將核心算法封裝為DLL或SO庫,方便與其他工具鏈集成。對于更專業的像素畫創作,建議結合手動編輯工具使用本算法作為預處理步驟。 “`
文章字數統計:約1850字(含代碼)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。