使用 c++ 将图像转换为 ASCII 艺术

64aff602c453a29084b0bef48edeb2d8.jpeg

什么是 Ascii 艺术?

ASCII艺术是一种图形设计技术,使用计算机进行演示,由1963年ASCII标准定义的95个可打印字符(总共128个)和ASCII兼容字符集(超过标准7位ASCII的128个字符)拼凑而成。该术语也被广泛用于指代基于文本的视觉艺术。

先决条件

  • 安装和配置OpenCV 库

    • OpenCV 安装教程:https://docs.opencv.org/4.x/df/d65/tutorial_table_of_content_introduction.html

  • CMake 已安装和配置

    • CMake 安装教程:https://cmake.org/install/

创建CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(image_to_ascii VERSION 0.1.0)

include(CTest)
enable_testing()

find_package(OpenCV REQUIRED)
include_directories((${OpenCV_INCLUDE_DIRS}))

add_executable(image_to_ascii main.cpp)

target_link_libraries(image_to_ascii ${OpenCV_LIBS})

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

创建一个main.cpp,包含所有必要导入的文件

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <math.h>

int main(int, char **)
{
    return 0;
}

使用 opencv 的imread方法读取图像,该方法返回一个Mat对象。

Mat 类表示一个 n 维密集数值单通道(灰度图像)或多通道(彩色图像)数组

cv::Mat image = cv::imread("pikachu.jpg");

将图像转换为灰度图像

ecd1a773a875132a6765775bd30aacb4.png

彩色图像到灰度图像

cv::Mat grayImage;
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);

声明并实现获取灰度图像像素平方平均值的calculateAvg函数

6d8b97eafb508d69eba4c6a23c1d9d27.png
int calculateAvg(cv::Mat image, int row, int col, int scale)
{
    int sum = 0;
    int pixelCount = 0;
    int r = row, c = col;
    
    while (r <= row + scale && r < image.rows)
    {
        while (c <= col + scale && c < image.cols)
        {
            sum += (int)image.at<uchar>(r, c);
            pixelCount++;
            c++;
        }
        r++;
    }
    
    return sum / pixelCount;
}

声明 ascii 代表的灰度值

std::string gscale = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ";

在 scale x scale 组中遍历图像的像素,并将 scale x scale 像素方形转换为1个ascii字符

int scale = 4;

for (int i = 0; i < grayImage.rows; i += scale)
{
    std::string text = "";
    
    for (int j = 0; j < grayImage.cols; j += scale)
    {
        // gray color in range (0, 255)
        int pixel = calculateAvg(grayImage, i, j, scale);
        // 2 ascii character will match 1 pixel, because 1 ascii character height match 2 ascii character width
        // so 2 ascii character will be a square
        text += gscale[ceil((gscale.length() - 1) * pixel / 255)];
        text += gscale[ceil((gscale.length() - 1) * pixel / 255)];
    }

        std::cout << text << std::endl;
}

现在,如果你构建 CMake 项目并运行该程序,它应该转换你的输入图像并在控制台中打印 ascii 艺术图像。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

a89afeef494a64580e7aa8a05641d910.jpeg

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值