"O Festival do Meio Outono está chegando" Eu não esperava poder desenhar um bolo lunar tão lindo usando OpenCV "Código-fonte anexado"

I. Introdução

O Festival do Meio Outono está chegando. Sendo um dos festivais tradicionais chineses, além de saborear deliciosos bolos lunares e admirar a lua, as pessoas também gostam de expressar sua alegria e bênçãos por este festival através de pinturas. Hoje em dia, com o desenvolvimento contínuo da tecnologia, é realmente revelador que você possa usar a biblioteca de visão computacional OpenCV para desenhar bolos lunares requintados e lindas imagens de coelhos de jade.

OpenCV, nome completo Open Source Computer Vision Library, é uma biblioteca de código aberto amplamente utilizada no campo da visão computacional. Ele fornece muitas funções poderosas de processamento de imagem e visão computacional, fornecendo aos desenvolvedores ferramentas e funções ricas, tornando relativamente fácil a implementação de várias operações de imagem. Sua flexibilidade e eficiência são preferidas pela maioria dos desenvolvedores.

Em um momento especial como o Festival do Meio Outono, usar OpenCV para desenhar imagens de bolos lunares e coelhos de jade pode não apenas mostrar respeito e apoio à cultura tradicional, mas também combinar o poder da tecnologia moderna para criar obras únicas e requintadas. Através do OpenCV, você pode desenhar bolos lunares com uma forte atmosfera festiva, seja pela aparência suave ou pela textura irregular, eles podem ser exibidos de forma vívida na sua frente. Ao mesmo tempo, usar OpenCV para desenhar a imagem do coelho de jade pode mostrar um estilo fofo de desenho animado, combinando elementos tradicionais com tendências da moda, proporcionando às pessoas uma sensação refrescante.

Além de desenhar bolos lunares e coelhos de jade, o OpenCV também oferece diversas funções de desenho, como desenhar formas geométricas básicas, linhas e texto, proporcionando uma ampla gama de espaço criativo. Ao chamar essas funções, você pode facilmente realizar várias necessidades de desenho e adicionar efeitos visuais exclusivos aos seus trabalhos.

Ao usar o OpenCV, primeiro você precisa instalar os arquivos da biblioteca correspondentes e familiarizar-se com seu uso. Ao aprender as operações básicas e chamadas de função do OpenCV, você pode utilizar melhor esta ferramenta poderosa para concretizar suas próprias ideias. Quer você seja um desenvolvedor profissional de visão computacional ou um iniciante interessado em processamento de imagens, dominar o OpenCV é uma boa escolha.

Neste Festival do Meio Outono, você também pode tentar usar o OpenCV para desenhar bolos lunares requintados e lindas imagens de coelhos de jade e sentir a colisão da cultura tradicional e da tecnologia moderna. Use um pincel para pintar na tela do computador, congele esse lindo momento e dê as boas-vindas ao Festival do Meio Outono junto com o poder do OpenCV.

Esta é a renderização ideal de uma exibição de imagem de carregamento.
imagem-20230913175620586

imagem-20230913175512032

2. Desenhe uma amostra de exibição

imagem-20230913175222845

imagem-20230913175457441

imagem-20230913175725373

imagem-20230913175752185

3. Instalação do OpenCV

3.1 Baixar OpenCV

Endereço de download do OpenCV: https://opencv.org/releases/page/3/

A versão mais recente é 4.3, então baixe a versão mais recente.

imagem-20230906101920240

imagem-20230906102004369

O download é um arquivo exe, que pode ser instalado clicando duas vezes nele. Na verdade, é descompactado. Você pode escolher o caminho de descompactação. O arquivo descompactado contém muitos arquivos de origem e arquivos de biblioteca. É relativamente grande e pode ser colocado diretamente em um diretório fixo. Os procedimentos a seguir Basta preencher o caminho diretamente para chamá-lo. Este arquivo de biblioteca baixado contém apenas a biblioteca X64, que é adequada para o compilador MSVS de 64 bits.

imagem-20230906102712398

A descompressão está completa.

imagem-20230906103311462

Após a descompactação, você verá os diretórios para VC14 e VC15 no diretório de construção. O que isto significa?

A diferença entre OpenCV VC14 e VC15 é a versão do compilador que eles usam. VC14 usa o compilador Visual Studio 2015, enquanto VC15 usa o compilador Visual Studio 2017. Isso significa que o VC15 pode aproveitar as vantagens de uma tecnologia de compilador mais avançada, melhorando assim o desempenho e a eficiência do seu código. Além disso, o VC15 também oferece suporte a mais recursos C++11 e C++14, tornando o desenvolvimento mais conveniente e flexível.

imagem-20230906103633870

3.2 Ambiente VS2022

Aqui apresentarei o processo de instalação do ambiente que utilizo. Todas as versões do VS estão disponíveis. OpenCV é apenas uma biblioteca de terceiros e pode ser chamada em qualquer lugar.

Meu ambiente atual é Windows e o IDE que uso é o IDEVS2022 mais forte que existe.

Endereço de download: https://visualstudio.microsoft.com/zh-hans/downloads/

imagem-20230913173131481

Como eu só preciso usar programação em linguagem C++ e C aqui, você pode escolher os pacotes que precisa instalar durante a instalação.

imagem-20230913173258088

Após a instalação, crie o projeto.

imagem-20230913173330580

imagem-20230913173349914

3.3 Nova construção

Este é um projeto vazio que criei. Escrevi um trecho de código OpenCV.

imagem-20230913173536785

Após a criação do projeto, você precisa adicionar uma referência ao arquivo de cabeçalho OpenCV e uma referência ao arquivo de biblioteca OpenCV.

Clique nesta propriedade.

imagem-20230913173632169

A primeira etapa é adicionar o caminho do arquivo de cabeçalho OpenCV usado em C++ e opções gerais.

imagem-20230913173709390

Onde exatamente esse caminho está depende do caminho de instalação do OpenCV.

imagem-20230913173753881

Para comodidade de todos, posto aqui.

C:/opencv_4.x/opencv/build/include/opencv2
C:/opencv_4.x/opencv/build/include/opencv
C:/opencv_4.x/opencv/build/include

A segunda etapa é definir o caminho para o arquivo da biblioteca. Em Opções de entrada do vinculador, adicione opções de dependência.

imagem-20230913173957033

Onde está esta biblioteca? Preencha com base no seu caminho de descompactação OpenCV.

imagem-20230913174030657

Este é o meu caminho:

C:/opencv_4.x/opencv/build/x64/vc15/lib/opencv_world430.lib

3.4 Cópia da biblioteca de tempo de execução

Se você escreveu o código OpenCV, basta pressionar para Ctrl + F5executar o programa. Se você executá-lo pela primeira vez, um erro será relatado.

As dicas são as seguintes:

imagem-20230913174225139

Este prompt nos informa que a biblioteca de tempo de execução OpenCV não pode ser encontrada quando o programa está em execução. Contanto que você use uma biblioteca de terceiros, você precisa saber disso: ao executar, você precisa copiar a biblioteca usada para o mesmo diretório de nível do exe gerado.

Copie os arquivos do diretório de descompactação OpenCV opencv_world430.dllpara o diretório no mesmo nível do exe compilado. Caso contrário, o programa terminará de forma anormal porque a biblioteca não pode ser encontrada.

imagem-20230912102245746

Copie aqui.

imagem-20230913174403148

Execute-o novamente e o programa funcionará normalmente.

imagem-20230913175414887

4. Introdução às funções de desenho OpenCV

OpenCV fornece uma série de funções para processamento e desenho de imagens, incluindo algumas funções de desenho comumente usadas. A seguir estão algumas das funções de desenho comumente usadas:

4.1 cv::line: Desenhar uma linha reta

void cv::line(cv::Mat& img, cv::Point pt1, cv::Point pt2,
              const cv::Scalar& color, int thickness=1,
              int lineType=cv::LINE_8, int shift=0);

Descrição do parâmetro:

  • img: A imagem para desenhar uma linha reta.
  • pt1: As coordenadas do ponto inicial da linha reta.
  • pt2: As coordenadas do ponto final da linha reta.
  • color: A cor da linha.
  • thickness: Largura da linha reta, o padrão é 1.
  • lineType: O tipo de linha reta, o padrão é linha conectada em 8 ( cv::LINE_8).
  • shift: O número de casas decimais para coordenadas, o padrão é 0.

4.2 cv::retangle: Desenhe um retângulo

void cv::rectangle(cv::Mat& img, cv::Rect rect, const cv::Scalar& color,
                   int thickness=1, int lineType=cv::LINE_8,
                   int shift=0);

Descrição do parâmetro:

  • img: A imagem do retângulo a ser desenhado.
  • rect: As informações de tamanho e posição do retângulo, ou seja, as coordenadas do canto superior esquerdo, largura e altura.
  • color:A cor do retângulo.
  • thickness: Largura da linha do retângulo, o padrão é 1.
  • lineType: O tipo de retângulo, o padrão é linha conectada em 8 ( cv::LINE_8).
  • shift: O número de casas decimais para coordenadas, o padrão é 0.

4.3 cv::circle: Desenhe um círculo

void cv::circle(cv::Mat& img, cv::Point center, int radius,
                const cv::Scalar& color, int thickness=1,
                int lineType=cv::LINE_8, int shift=0);

Descrição do parâmetro:

  • img: Para desenhar uma imagem circular.
  • center: As coordenadas do centro do círculo.
  • radius: O raio do círculo.
  • color: A cor do círculo.
  • thickness: A largura da linha do círculo, o padrão é 1.
  • lineType: O tipo de círculo, o padrão é linha 8 conectada ( cv::LINE_8).
  • shift: O número de casas decimais para coordenadas, o padrão é 0.

4.4 cv::ellipse: desenhe uma elipse

void cv::ellipse(cv::Mat& img, cv::Point center,
                 cv::Size axes, double angle, double startAngle,
                 double endAngle, const cv::Scalar& color,
                 int thickness=1, int lineType=cv::LINE_8,
                 int shift=0);

Descrição do parâmetro:

  • img: Para desenhar uma imagem elíptica.
  • center: As coordenadas do centro da elipse.
  • axes: O tamanho dos eixos maior e menor da elipse.
  • angle: O ângulo de rotação da elipse, em graus.
  • startAngle: O ângulo inicial da elipse, em graus.
  • endAngle: O ângulo final da elipse, em graus.
  • color:A cor da elipse.
  • thickness: A largura da linha da elipse, o padrão é 1.
  • lineType: O tipo de elipse, o padrão é linha 8 conectada ( cv::LINE_8).
  • shift: O número de casas decimais para coordenadas, o padrão é 0.

4.5 cv::putText: Desenha texto na imagem

void cv::putText(cv::Mat& img, const std::string& text,
                 cv::Point org, int fontFace, double fontScale,
                 const cv::Scalar& color, int thickness=1,
                 int lineType=cv::LINE_8, bool bottomLeftOrigin=false);

Descrição do parâmetro:

  • img: A imagem na qual desenhar o texto.
  • text: O conteúdo do texto a ser desenhado.
  • org: As coordenadas do canto inferior esquerdo do texto.
  • fontFace: Tipo de fonte.
  • fontScale: A proporção de escala da fonte.
  • color: A cor da fonte.
  • thickness: A largura da linha da fonte, o padrão é 1.
  • lineType: Tipo de fonte, o padrão é 8 linhas conectadas ( cv::LINE_8).
  • bottomLeftOrigin: Seja para tomar o canto inferior esquerdo como origem, o padrão é falso, ou seja, o canto superior esquerdo é a origem.

4.6 cv::polylines: Desenhe os limites dos polígonos.

void cv::polylines(cv::Mat& img, const cv::Point* pts,
                   const int* npts, int ncontours,
                   bool isClosed, const cv::Scalar& color,
                   int thickness=1, int lineType=cv::LINE_8,
                   int shift=0);

Descrição do parâmetro:

  • img: A imagem do polígono a ser desenhado.
  • pts: matriz de coordenadas de cada vértice do polígono.
  • npts: Matriz do número de vértices de cada circuito fechado do polígono.
  • ncontours: O número de polígonos.
  • isClosed: Se deseja fechar o polígono.
  • color: A cor do polígono.
  • thickness: Largura da linha do limite do polígono, o padrão é 1.
  • lineType: O tipo de polígono, o padrão é linha 8 conectada ( cv::LINE_8).
  • shift: O número de casas decimais para coordenadas, o padrão é 0.

4.7 cv::fillPoly: Preenche dentro do polígono.

void cv::fillPoly(cv::Mat& img, const cv::Point** pts,
                  const int* npts, int ncontours,
                  const cv::Scalar& color,
                  int lineType=cv::LINE_8, int shift=0,
                  cv::Point offset=cv::Point());

Descrição do parâmetro:

  • img: A imagem com a qual preencher o polígono.
  • pts: ponteiro para a matriz de coordenadas de cada vértice do polígono.
  • npts: Matriz do número de vértices de cada circuito fechado do polígono.
  • ncontours: O número de polígonos.
  • color: Cor de preenchimento.
  • lineType: O tipo de polígono, o padrão é linha 8 conectada ( cv::LINE_8).
  • shift: O número de casas decimais para coordenadas, o padrão é 0.
  • offset: Deslocamento ao preencher polígonos.

4.8 Exemplos de uso de cv::polylines e cv::fillPoly

cv::Mat image(500, 500, CV_8UC3, cv::Scalar(255, 255, 255));  // 创建一张白色图像

// 定义多边形的顶点坐标
cv::Point pts[1][4];
pts[0][0] = cv::Point(100, 100);
pts[0][1] = cv::Point(200, 100);
pts[0][2] = cv::Point(200, 200);
pts[0][3] = cv::Point(100, 200);

// 绘制多边形的边界
const cv::Point* ppt[1] = {
    
     pts[0] };
int npt[] = {
    
     4 };
cv::polylines(image, ppt, npt, 1, true, cv::Scalar(0, 0, 255), 2);

// 填充多边形的内部
cv::fillPoly(image, ppt, npt, 1, cv::Scalar(0, 255, 0));

// 显示图像
cv::imshow("Image", image);
cv::waitKey(0);

Este código de exemplo cria uma imagem branca e desenha um retângulo com borda vermelha na imagem, enquanto preenche o interior do retângulo com verde. Usando cv::polylinesas funções e cv::fillPoly, você pode desenhar formas poligonais e efeitos de preenchimento mais complexos.

5. Códigos de desenho Mooncake e Jade Rabbit

5.1 O bolo lunar mais simples

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个黑色背景图像作为画布
    cv::Mat canvas(400, 400, CV_8UC3, cv::Scalar(0, 0, 0));

    // 定义月饼的参数
    cv::Point center(canvas.cols / 2, canvas.rows / 2);
    int radius = 150;
    cv::Scalar mooncakeColor(139, 69, 19); // 棕色

    // 绘制月饼的主体
    cv::circle(canvas, center, radius, mooncakeColor, cv::FILLED);

    // 在窗口中显示绘制的月饼
    cv::imshow("Circular Mooncake", canvas);
    cv::waitKey(0);

    return 0;
}

O código cria uma imagem de fundo preta com tamanho de 400x400 pixels e usa cv::circle()a função para desenhar um bolo lunar redondo e marrom. Desenhe um mooncake circular especificando as coordenadas centrais, o raio e a cor. Finalmente, o mooncake desenhado é exibido na janela.

5.2 O Coelho de Jade mais simples

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个黑色背景图像作为画布
    cv::Mat canvas(400, 400, CV_8UC3, cv::Scalar(0, 0, 0));

    // 绘制兔子身体
    cv::ellipse(canvas, cv::Point(canvas.cols / 2, canvas.rows / 2), cv::Size(150, 200), 0, 0, 360, cv::Scalar(255, 255, 255), cv::FILLED);

    // 绘制兔子内耳朵
    cv::ellipse(canvas, cv::Point(canvas.cols / 2 - 60, canvas.rows / 2 - 110), cv::Size(70, 100), 0, 0, 360, cv::Scalar(255, 255, 255), cv::FILLED);
    cv::ellipse(canvas, cv::Point(canvas.cols / 2 + 60, canvas.rows / 2 - 110), cv::Size(70, 100), 0, 0, 360, cv::Scalar(255, 255, 255), cv::FILLED);

    // 绘制兔子眼睛
    cv::circle(canvas, cv::Point(canvas.cols / 2 - 40, canvas.rows / 2), 20, cv::Scalar(0, 0, 0), cv::FILLED);
    cv::circle(canvas, cv::Point(canvas.cols / 2 + 40, canvas.rows / 2), 20, cv::Scalar(0, 0, 0), cv::FILLED);

    // 绘制兔子嘴巴
    cv::ellipse(canvas, cv::Point(canvas.cols / 2, canvas.rows / 2 + 60), cv::Size(60, 30), 0, 180, 360, cv::Scalar(0, 0, 0), cv::FILLED);

    // 绘制兔子鼻子
    cv::circle(canvas, cv::Point(canvas.cols / 2, canvas.rows / 2 + 40), 10, cv::Scalar(255, 0, 0), cv::FILLED);

    // 在窗口中显示绘制的兔子
    cv::imshow("Rabbit", canvas);
    cv::waitKey(0);

    return 0;
}

O código l cria uma imagem de fundo preto com tamanho de 400x400 pixels e usa as funções cv::ellipse()e cv::circle()para desenhar o corpo, a parte interna das orelhas, os olhos, a boca e o nariz do coelho. Desenhe diferentes partes especificando parâmetros como ponto central, tamanho, ângulo e cor. Por fim, o coelho desenhado é exibido na janela.

5.3 Desenhe bolos lunares com contornos padronizados

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个画布,大小为800x800像素
    cv::Mat canvas(800, 800, CV_8UC3, cv::Scalar(255, 255, 255));

    // 设置画笔属性
    int thickness = 20;
    cv::Scalar color(245, 225, 111); // 黄色
    int lineType = cv::LINE_8;

    // 绘制太阳花花瓣
    for (int i = 0; i < 20; ++i)
    {
    
    
        // 计算当前花瓣的角度
        double angle = i * 18.0;

        // 计算当前花瓣的终点坐标
        double x = 400 + 220 * cos(angle * CV_PI / 180);
        double y = 400 + 220 * sin(angle * CV_PI / 180);

        // 绘制直线
        cv::line(canvas, cv::Point(400, 400), cv::Point(x, y), color, thickness, lineType);

        // 绘制半圆
        cv::Point center(x, y);
        cv::ellipse(canvas, center, cv::Size(40, 40), 0, 180, 360, color, -1);
    }

    // 绘制中心圆
    cv::Scalar fill_color(255, 153, 51); // 橙色
    cv::Point center(400, 400);
    cv::circle(canvas, center, 200, fill_color, -1);

    // 绘制花瓣图案
    cv::Scalar petal_color(245, 225, 111); // 黄色
    for (int i = 0; i < 12; ++i)
    {
    
    
        // 计算当前花瓣的起点和终点角度
        double startAngle = i * 30.0;
        double endAngle = startAngle + 120.0;

        // 绘制圆弧
        cv::ellipse(canvas, center, cv::Size(60, 60), 0, startAngle, endAngle, petal_color, -1);

        // 旋转180度,绘制对称的圆弧
        cv::ellipse(canvas, center, cv::Size(60, 60), 0, startAngle + 180, endAngle + 180, petal_color, -1);
    }

    // 显示结果
    cv::imshow("Sunflower", canvas);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

O código cria uma tela de 800x800 pixels e usa funções e métodos OpenCV para desenhar o padrão de girassol. cv::line()Desenhe linhas retas, cv::circle()desenhe círculos, cv::ellipse()desenhe semicírculos e arcos.

5.4 Desenhando um coelho

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个800x800像素的画布
    cv::Mat canvas(800, 800, CV_8UC3, cv::Scalar(255, 255, 255));

    // 设置画笔属性
    int thickness = -1; // 填充形状
    cv::Scalar color(0, 0, 0); // 黑色
    int lineType = cv::LINE_8;

    // 绘制兔子的头部
    cv::Point center(400, 400);
    cv::circle(canvas, center, 60, color, thickness, lineType);

    // 绘制兔子的眼睛
    cv::Point eye1(380, 500);
    cv::Point eye2(420, 500);
    cv::circle(canvas, eye1, 25, color, thickness, lineType);
    cv::circle(canvas, eye2, 25, color, thickness, lineType);

    // 绘制兔子的嘴巴
    cv::Point mouth_center(400, 480);
    cv::Size axes(10, 10);
    cv::ellipse(canvas, mouth_center, axes, 0, 0, 180, color, thickness, lineType);

    // 绘制兔子的身体
    cv::circle(canvas, center, 100, color, thickness, lineType);

    // 绘制兔子的脚
    cv::Point foot1(340, 600);
    cv::Point foot2(460, 600);
    cv::ellipse(canvas, foot1, axes, 0, 0, 180, color, thickness, lineType);
    cv::ellipse(canvas, foot2, axes, 0, 0, 180, color, thickness, lineType);

    // 绘制兔子的尾巴
    cv::Point tail(480, 400);
    cv::circle(canvas, tail, 20, color, thickness, lineType);

    // 显示结果
    cv::imshow("Rabbit", canvas);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

O código cria uma tela de 800x800 pixels e desenha a cabeça, os olhos, a boca, o corpo, os pés e a cauda do coelho.

5.5 Desenho da versão Fairy Chang'e-Lite

#include <opencv2/opencv.hpp>

int main()
{
    
    
    // 创建一个800x800像素的画布
    cv::Mat canvas(800, 800, CV_8UC3, cv::Scalar(255, 255, 255));

    // 设置画笔属性
    int thickness = -1; // 填充形状
    cv::Scalar color(0, 0, 0); // 黑色
    int lineType = cv::LINE_8;

    // 绘制头部
    cv::Point head_center(400, 300);
    cv::circle(canvas, head_center, 80, color, thickness, lineType);

    // 绘制眼睛
    cv::Point eye1(360, 270);
    cv::Point eye2(440, 270);
    cv::circle(canvas, eye1, 10, color, thickness, lineType);
    cv::circle(canvas, eye2, 10, color, thickness, lineType);

    // 绘制嘴巴
    cv::Point mouth_center(400, 330);
    cv::Size axes(30, 30);
    cv::ellipse(canvas, mouth_center, axes, 0, 0, 180, color, thickness, lineType);

    // 绘制身体
    cv::Point body_top(400, 380);
    cv::Point body_bottom(400, 550);
    cv::line(canvas, body_top, body_bottom, color, 2, lineType);

    // 绘制衣裙
    cv::Point skirt_top(370, 550);
    cv::Point skirt_bottom(430, 700);
    cv::line(canvas, body_bottom, skirt_top, color, 2, lineType);
    cv::rectangle(canvas, cv::Rect(350, 570, 100, 130), color, thickness, lineType);

    // 绘制左手
    cv::Point hand1_start(400, 420);
    cv::Point hand1_end(320, 500);
    cv::line(canvas, hand1_start, hand1_end, color, 2, lineType);

    // 绘制右手
    cv::Point hand2_start(400, 420);
    cv::Point hand2_end(480, 500);
    cv::line(canvas, hand2_start, hand2_end, color, 2, lineType);

    // 绘制发髻
    cv::Point hair_top(400, 200);
    cv::Size hair_axes(80, 40);
    cv::ellipse(canvas, hair_top, hair_axes, 0, 180, 360, color, thickness, lineType);

    // 绘制发丝
    cv::Point hair1_start(400, 160);
    cv::Point hair1_end(320, 220);
    cv::line(canvas, hair1_start, hair1_end, color, 2, lineType);

    cv::Point hair2_start(400, 160);
    cv::Point hair2_end(480, 220);
    cv::line(canvas, hair2_start, hair2_end, color, 2, lineType);

    // 显示结果
    cv::imshow("Chang'e", canvas);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}


Foi criada uma tela de 800x800 pixels e desenhados a cabeça, os olhos, a boca, o corpo, as mãos, o vestido e o coque da Fada Chang'e.

6. Resumo

O Festival do Meio Outono é um dos festivais importantes da cultura tradicional chinesa, e usar OpenCV para desenhar imagens requintadas de bolo lunar e coelho de jade é um movimento inovador que combina tradição e tecnologia. Através das poderosas funções do OpenCV, efeitos visuais únicos podem ser exibidos, dando um novo charme aos elementos tradicionais. Ao mesmo tempo, esta é também uma expressão única do Festival do Meio Outono, permitindo a todos sentir a surpresa e a diversão que a tecnologia moderna nos traz enquanto degustam mooncakes e admiram a lua.

Quer você seja um desenvolvedor profissional ou um entusiasta comum, aprender e dominar o OpenCV pode liberar melhor sua imaginação e criatividade e criar seus próprios trabalhos requintados. Neste Festival especial do Meio Outono, com a ajuda da magia do OpenCV, você pode sentir o encanto da cultura tradicional e o poder da tecnologia moderna no processo de desenho de bolos lunares e coelhos de jade. Use a criatividade e a tecnologia para adicionar mais alegria e bênçãos a este festival maravilhoso.

Desde já ----> Desejo a todos um feliz Festival do Meio Outono e um reencontro para aqueles que estão sob a lua cheia!

Acho que você gosta

Origin blog.csdn.net/xiaolong1126626497/article/details/132874507
Recomendado
Clasificación