Tecnologia de reconhecimento de imagem OpenCV | Versão C++

Começando

Imagem e sinal

imagem

A imagem é a reprodução material da percepção humana da visão. As imagens podem ser adquiridas por dispositivos ópticos ou criadas artificialmente. Com o desenvolvimento da tecnologia de aquisição digital e da teoria do processamento de sinal, mais e mais imagens são armazenadas em formato digital. Assim, em alguns casos, o termo "imagem" realmente se refere a uma imagem digital. Tópicos relacionados a imagens incluem aquisição de imagens, produção de imagens, análise de imagens e processamento de imagens. As imagens são divididas em imagens estáticas e imagens em movimento. Uma imagem é um sinal visual. Por meio de imagens elaboradas profissionalmente, é possível desenvolver uma linguagem visual para a comunicação entre as pessoas, podendo também ser um material histórico para a compreensão da cultura étnica e das origens históricas. Um grande número de pinturas bidimensionais, esculturas tridimensionais e edifícios na história da arte mundial também podem ser considerados como a imagem de bens culturais desenvolvidos pela civilização humana desde os tempos antigos até o presente.

Sinal

Na teoria da informação, um sinal é um fluxo de informação. A maioria dos sinais de interesse pode ser expressa como funções de tempo ou posição. Qualquer quantidade física que carregue informação pode ser usada como um sinal. A informação transportada pelo próprio sinal é nosso objetivo, extrair sinais úteis dele e suprimir o objetivo de processamento de sinal da parte de interferência. Um sinal contínuo em todas as dimensões é um sinal analógico, e um sinal discreto em todas as dimensões é um sinal matemático. Sinais matemáticos são gerados discretizando sinais analógicos em dimensões de tempo e amplitude.

Representação e classificação de sinal de imagem digital
imagem binária

O valor de brilho de cada pixel em uma imagem só pode ser obtido de uma imagem de 0 ou 1, por isso também é chamada de imagem de 1 bit. Uma imagem binarizada é uma imagem que contém apenas dois valores de sinal, que são mais usados ​​para representar a forma e o contorno da imagem.

imagem em tons de cinza

Também conhecida como imagem em tons de cinza. Cada pixel em uma imagem pode ser representado por um valor de brilho de 0 (preto) a 255 (branco). Entre 0-255 representam diferentes níveis de cinza. Quando os sinais de cores de um mapa de cores (como RGB) são iguais, como R=G=B, a imagem mostra um comportamento de transição de preto para branco. Frequentemente usado para representar a profundidade de cor de uma imagem. semelhante a um esboço em uma pintura

imagem colorida

As imagens coloridas são divididas principalmente em dois tipos, RGB e CMYK. A imagem colorida RGB é composta de três componentes de cores diferentes, um é vermelho, um é verde e um é azul. A imagem do tipo CMYK é composta por quatro componentes de cores: ciano C, magenta M, amarelo Y e preto K. As imagens do tipo CMYK são usadas principalmente na indústria de impressão. Full color significa que a cor do objeto na imagem é muito semelhante à cor vista a olho nu. Em imagens em preto e branco, cores referem-se ao brilho dos objetos. No entanto, como as propriedades químicas dos meios, como os corantes, são diferentes daquelas do olho humano, é impossível obter cores completas absolutas. Em uma imagem de cores falsas, a cor do objeto e a cor da imagem são alteradas, o que pode ocorrer em muitos lugares. Por exemplo, a cor de um filme negativo pode ser chamada de cor falsa, porque a cor do filme negativo é a cor complementar da cor do objeto. Mas a cor falsa é frequentemente usada para representar partes do espectro eletromagnético que não são visíveis. Como sensoriamento remoto e espectroscopia cósmica.

imagem em cores falsas
imagem multiespectral
imagem estereoscópica

As imagens estéreo são um par de imagens de um objeto tiradas de diferentes ângulos. Normalmente, podemos usar imagens estéreo para calcular as informações de profundidade da imagem. A imagem estereoscópica é adicionar luz de profundidade e informações de sombra no plano, o efeito visual (fazer a aparência da imagem) como o resultado visual da imagem estereoscópica "estereoscópica", enquanto a imagem tridimensional é a descrição da informação.

imagem 3D

Uma imagem 3D é composta por um conjunto de imagens 2D empilhadas. Cada imagem representa uma superfície bidimensional do objeto

Pixels das Propriedades da Imagem

informações de pixel

Pixel é a unidade básica de exibição de imagens, traduzida como "pixel" em inglês, pix é uma abreviação comum da palavra inglesa picture, mais a palavra inglesa "element" para obter pixel, então "pixel" significa "elemento de imagem" , às vezes Também conhecido como pel. Cada um desses elementos de mensagem não é um ponto ou um quadrado, mas uma amostra abstrata.

Veja a representação da imagem no monitor

A representação mais comum de uma tela é xx polegadas, e o parâmetro principal que representa a tela é PPI, que é pixels por polegada, também conhecido como densidade de pixels, portanto, pontos não são representações de imagens!

LDPI baixa densidade de pixels de cerca de 120 pixels por polegada (36 x 36 px)

Densidade média de pixels MDPI de cerca de 160 pixels por polegada (48 x 48 px)

Alta densidade de pixels HDPI aproximadamente 240 pixels por polegada (72 x 72 px)

Densidade de pixel muito alta XHDPI cerca de 320 pixels por polegada (96 x 96 px)

Densidade de pixel super alta XXHDPI aproximadamente 480 pixels por polegada (144 x 144 px)

bitmap

Bitmap (Inglês: Bitmap, Taiwan chamado bitmap), também conhecido como gráficos raster (Raster graphics), é uma imagem representada por uma matriz de pixels.

Quanto mais bits de informação forem usados ​​por pixel, mais cores estarão disponíveis, mais realista será a representação de cores e a correspondente maior quantidade de dados.

ilustração vetorial

Gráficos vetoriais são imagens representadas por primitivas geométricas baseadas em equações matemáticas como pontos, linhas ou polígonos em computação gráfica. Todos os monitores de computador modernos convertem gráficos vetoriais em um formato de imagem raster, e a imagem raster contém o valor de cada pixel na tela e é armazenada na memória.

Cor das propriedades da imagem

sistema visual humano

Na retina do olho humano, existem dois tipos de células fotorreceptoras: os bastonetes e os cones

Células bastonetes: funcionam principalmente em condições de pouca luz e não têm função de reconhecimento de cores, portanto, não podemos distinguir cores em condições de pouca luz.

Cones: funcionam em condições de muita luz. Em circunstâncias normais, existem três tipos de células cone na retina do olho humano que podem detectar vermelho (R), verde (G) e azul (B). S distingue principalmente onda curta, principalmente azul, M, onda média, principalmente verde, e L onda longa, principalmente vermelho.

N-cromatologista - um animal ou pessoa com N cones

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-bVWJ52xZ-1678179718427) (C:\Users\86166\AppData\Roaming\Typora \typora-user-images\ imagem-20211220212202851.png)]

Os camarões Pippi têm 16 tipos de células cone e podem ver 10 vezes mais cores do que os humanos, alcançando todos os animais da Terra. Eles podem ver ultravioleta, infravermelho e até luz polarizada.

Cores e Modelos
modelo GRB

Modelos que combinam com o principal sistema visual humano, construídos em cores primárias

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-GP3nyyNI-1678179718428) (C:\Users\86166\AppData\Roaming\Typora\ typora-user-images\ imagem-20211220213311152.png)]

modelo HSV

HSV é uma abreviação de Matiz, Saturação e Valor. Este modelo descreve as cores por meio dessas três características.

HSV (Hue Saturation Value), HSI (Hue Saturation Intensity) e HSL (Hue Saturation Lightness) são as três representações de coordenadas cilíndricas mais comuns de pontos no modelo de cores RGB.

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-alHkuODd-1678179718429) (C:\Users\86166\AppData\Roaming\Typora\ typora-user-images\ image-20211220213558708.png)]

modelo de laboratório

É um modelo de cores para equipamentos sem luz e é um modelo de cores baseado em características fisiológicas

O componente L no espaço de cores Lab é usado para representar o brilho do pixel, e o intervalo de valores é [0,100], que significa de preto puro a branco puro; a representa o intervalo de vermelho a verde e o intervalo de valores é [127,-128]; b representa o intervalo de amarelo a azul e o intervalo de valores é [127,-128].

O espaço de cores RGB não pode ser convertido diretamente para o espaço de cores Lab. É necessário usar o espaço de cores XYZ para converter o espaço de cores RGB para o espaço de cores XYZ e, em seguida, converter a cor XYZ para o espaço de cores Lab.

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-daxY8o6B-1678179718429) (C:\Users\86166\AppData\Roaming\Typora\ typora-user-images\ image-20211220214131250.png)]

modelo YUV

O modelo YUV é o método de codificação de cores usado pelo sistema de sinal de TV. Essas três variáveis ​​representam o brilho do pixel (Y) e a diferença de sinal entre o componente vermelho e o brilho (U) e a diferença entre o azul e o brilho (V)

O vídeo em preto e branco possui apenas o vídeo Y (Luma, Luminância), que é o valor da escala de cinza. Quando a especificação de TV em cores é especificada, as imagens de TV em cores são processadas no formato YUV/YIQ, e UV é considerado como C (Chrominance ou Chroma) representando croma. Se o sinal C for ignorado, o sinal Y (Luma) restante será É o mesmo número anterior da TV em preto e branco, o que resolve o problema de compatibilidade entre a TV em cores e a TV em preto e branco. A maior vantagem do Y'UV é que ele ocupa muito pouca largura de banda.
insira a descrição da imagem aqui

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-FoedbsmQ-1678179718430) (C:\Users\86166\AppData\Roaming\Typora\ typora-user-images\ imagem-20211220214620618.png)]

modelo cinza

O modelo GRAY não é um modelo colorido, é um modelo de imagem em tons de cinza e seu nome usa as letras maiúsculas da palavra inglesa gray.

A imagem em escala de cinza possui apenas um canal, e o valor da escala de cinza é representado de preto para branco em sequência de 0 ao máximo de acordo com o número de dígitos da imagem. Por exemplo, no formato 8UC1, é quantizado em 256 níveis de preto para branco , expresso por 0-255, dos quais 255 significa branco

Cinza = R* 0,299 + G * 0,587 + B * 0,114

Na verdade, esta fórmula é o algoritmo Y em YUV.

modelo CMYK

O modo de separação de quatro cores (CMYK) é um modo de registro de cores usado na impressão colorida. Ele usa o princípio da mistura de cores de três cores primárias de materiais coloridos, além de tinta preta, e um total de quatro cores são misturadas e sobrepostas para formar a chamada impressão colorida.

C: Cyan = ciano, muitas vezes chamado erroneamente de "céu azul" ou "azul"

M: Magenta = magenta, também conhecido como "magenta"

Y: amarelo = amarelo

K: preto = preto, (para evitar confusão com B em RGB, então use K)

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-51xqNirG-1678179718431) (C:\Users\86166\AppData\Roaming\Typora \typora-user-images\ imagem-20211220215745534.png)]

Outros termos profissionais:

Shade: A cor trazida pelo espectro na verdade se refere ao modelo RGB

Material de cor: a cor usada para pintar, geralmente se refere à cor no modelo CMYK

Matiz: Combine leveza e croma em matiz. Conforme mostrado na figura abaixo: [Vermelho] é a tonalidade e [Fresh, Light, Pink] é a tonalidade

Formato de imagem detalhado

Comparação de formato de imagem

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-fCG8Ee1V-1678179718431) (C:\Users\86166\AppData\Roaming\Typora\ typora-user-images\ imagem-20211220224330898.png)]

Formato de imagem comum bmp

BMP é (Windows Bitmap) Um Windows Bitmap pode armazenar uma única imagem raster em qualquer intensidade de cor (de preto e branco a cores de 24 bits). O formato de arquivo bitmap do Windows é compatível com outros programas do Microsoft Windows. Ele não suporta compactação de arquivos nem é adequado para páginas da web. No geral, as desvantagens do formato de arquivo bitmap do Windows superam suas vantagens. Para garantir a qualidade das imagens fotográficas, use arquivos PNG, JPEG, TIFF. Os arquivos BMP são adequados para papéis de parede do Windows.

Prós: BMP suporta profundidade de cor de 1 bit a 24 bits.

O formato BMP é amplamente compatível com os programas existentes do Windows, especialmente os mais antigos

Desvantagens: BMP não suporta compactação, o que resultará em arquivos muito grandes.

Formato de imagem comum JPEG (.jpg .jpeg)

É um formato de compactação com perdas, que pode compactar a imagem em um pequeno espaço de armazenamento. Dados repetidos ou sem importância na imagem serão perdidos, por isso é fácil causar danos aos dados da imagem. Em particular, usar uma taxa de compactação excessivamente alta reduzirá significativamente a qualidade da imagem recuperada após a descompactação final. Se você busca imagens de alta qualidade, não deve usar uma taxa de compactação excessivamente alta.

vantagem:

Trabalhos fotográficos ou realistas suportam compactação avançada.

O tamanho do arquivo pode ser controlado com uma taxa de compactação variável.

O entrelaçamento é suportado (correspondente a arquivos JPEG progressivos).

O JPEG é amplamente suportado como um padrão da Internet.

deficiência:

A compactação com perdas degrada a qualidade dos dados da imagem original.

Quando você edita e salva novamente um arquivo JPEG, o JPEG mistura a qualidade dos dados da imagem original com degradação. Essa queda é cumulativa.

O JPEG não é adequado para imagens mais simples que contenham poucas cores, tenham grandes áreas de cores semelhantes ou tenham diferenças significativas no brilho.

formato png

Portable Network Graphics (abreviado como PNG em língua estrangeira, nome completo em língua estrangeira: Portable Network Graphics), é o formato de arquivo de imagem mais recente aceito na Internet. O PNG pode fornecer arquivos de imagem compactados sem perdas que são 30% menores que o GIF. Ele também oferece suporte a imagens em cores verdadeiras de 24 bits e 48 bits e muitos outros suportes técnicos.

prioridade:

O PNG oferece suporte a um alto nível de compactação sem perdas.

O PNG oferece suporte à transparência do canal alfa.

PNG suporta correção de gama.

PNG suporta entrelaçamento.

O PNG é compatível com os navegadores da Web mais recentes.

deficiência:

Navegadores e programas mais antigos podem não oferecer suporte a PNG.

Como formato de arquivo interno, o PNG oferece menos compactação do que a compactação com perdas do JPEG.

Como formato de arquivo interno, o PNG não oferece suporte para arquivos com várias imagens ou arquivos de animação. O formato GIF oferece suporte a vários arquivos de imagem e suporte a animação.

Mat classe e funções básicas

Método de aprendizado de estrutura de código aberto e análise geral da classe Mat

Se você aprender a estrutura de código aberto

Geral :

(1) Qual é o papel da estrutura de código aberto?

1. Em que áreas pode ser aplicado
2. Qual é a estrutura geral?

(2) Como usar a estrutura de código aberto

1. Casos públicos de uso de frameworks de código aberto
2. Tome o OpenCV como exemplo:
quais classes existem
e quais métodos existem

(3) Compreender a lógica de design de estruturas de código aberto

1. Tome o OpenCV como exemplo,
quais módulos existem, quais são as funções de cada módulo e como os módulos são conectados entre si?
​​2. Observe o código-fonte para análise

Detalhes (pegue a classe Mat como exemplo)

(1) Análise sob a perspectiva dos módulos

Mat->matriz matriz

[1,1]

Contêiner -> contêiner para armazenar dados

Armazenar informações da imagem

Imagem:

mapa binário

imagem colorida

Gráfico de dados

(2) Análise a partir do significado da linguagem

tipo:

Atributos:

linha, coluna, dados, dimensão

Tipos de imagens

Método:

Método de operação de matriz, método de obtenção/configuração de atributos

Diferentes tipos de configurações de imagem

​ Construtor/Destruidor·········

Método de gerenciamento de memória:

​ (1) Sem gerenciamento de memória, puramente pelo sistema

​ (2) Gerenciamento manual, confiando apenas nos programadores para projetar o código

​ (3) Gerenciamento de GC, coleta de lixo, tempo ou intervalo, recuperar espaço desnecessário

​ (4) Gerenciamento de contagem de referência, RC, se houver uma nova referência, a contagem de referência é +1, e se a referência antiga desaparecer, a contagem de referência é -1. Quando a contagem de referência cair para 0, a memória será recuperada, que é a maneira como os objetos OpenCV funcionam

(5) Gerenciamento do pool de memória. Semelhante ao gerenciamento de aquários, este método é geralmente usado como um método de gerenciamento auxiliar ou um método de gerenciamento geral.

Como ver o código-fonte

(1) Para linguagem c

A função é o método de divisão do módulo da linguagem C, e o ponto chave é analisar o método de implementação de cada função

(2) Para C++

módulo

tipo

variável de membro de atributo

Função do método:

(1) atributos

(2) método

(3) Método de gerenciamento de memória

Memória e métodos da classe Mat

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;
void printMat(Mat &mat) {
    cout << "Mat:" << mat << endl;
    cout << "flags:" << mat.flags << endl;
    cout << "dims:" << mat.dims << endl;
    cout << "rows:" << mat.rows << "cols:" << mat.cols << endl;
    if (mat.data)
    {
        cout << "data:存在" << endl;
    }
    
    cout << "存储相关:" << endl;
    cout << "umatadata:" << mat.u << endl;
    if (mat.u->refcount){
        cout << "refcount:" << mat.u->refcount << endl;
    }
    
}

int main(int argc, char const *argv[])
{
    //仅创建对应的矩阵头信息,没有包含真正的矩阵内部数据
    Mat m;

    //CV_8UC1 8指数据位数,U指是否带符号,Cchannel信道数,1一个信道
    Mat m_size(10, 10, CV_8UC1);
    //zeros进行元素数据清零操作
    m_size.zeros(10, 10, CV_8UC1);
    imshow("test", m_size);
    printMat(m_size);

    m = m_size;
    printMat(m);

    Mat m1 = m;
    printMat(m1);

    //上述两种方式,都是浅拷贝,只会增加对应的引用计数(refcount),而不会产生新的内存
    Mat mat_clone = m.clone();
    Mat mat_copy_to_mat;
    m.copyTo(mat_copy_to_mat);

    printMat(mat_clone);
    printMat(mat_copy_to_mat);
    //上述两种方式,是深拷贝,会产生新的内存,对应的引用计数不会增加


    Mat scalar_mat(100, 100, CV_8UC3, Scalar(128, 255, 0));
    imshow("scalar", scalar_mat);

    //获取对角线上的数据
    cout << scalar_mat.diag(0) << endl;

    //create 办法,进行数据的填充处理了,create之前的对象就被销毁了
    Mat un_create;
    printMat(un_create);

    un_create.create(10, 10, CV_8UC1);
    printMat(un_create);
    
    //waitKey(0);
    //Mat作用:
    //(1)用于数学上的矩阵运算(2)进行图像数据的存储和相关的运算操作
    return 0;
}

Método básico de processamento de imagem

#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
using namespace std;

int trackbarvalue;
Mat  image;


void trackbarcallback(int value, void *data) {
    cout << value << endl;

    image &= 1;
    image *= (value / 255.0);

    imshow("window_name", image);
}

void mouseEvenCallBack(int event, int x, int y, int falg, void *userdata) {
    cout << event << endl;
    cout << x << ":" << y << endl;
}

int main(int argc, char const *argv[])
{
    /*
    图像存取相关函数
    */
   //(1)图片的绝对路径或相对路径(2)读入图片到Mat容器当中的存取方式
   Mat srcImage = imread("../spand.jpg", IMREAD_GRAYSCALE);
    image = srcImage;
    //autosize 在部分环境下,可能无法改变窗口的大小 normal可以改变
    namedWindow("window_name", WINDOW_NORMAL);

    //添加进度条,注意使用回调函数
    createTrackbar("trackbar", "window_name", &trackbarvalue, 255, trackbarcallback);

    //鼠标的操作
    setMouseCallback("window_name", mouseEvenCallBack, (void *)&srcImage);

    //(1)显示的图片名称(2)图片的容器
    imshow("window_name", srcImage);

    /*
        1、保存的图片名称,注意需要带后缀名
        2、保存的源图片容器
        3、存储过程中的编码处理 比如压缩处理
    */
    vector<int> comparession;
    comparession.push_back(IMWRITE_PNG_COMPRESSION);
    comparession.push_back(9);
    imwrite("gray_logo1.jpg", srcImage, comparession);
    
    //键盘组操作  等待一个任意字符,参数为延迟时间
    waitKey(0);
    return 0;
}

método de desenho

#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    /*
        1、线Line
        2、矩形rectangle
        3、圆circle
        4、椭圆ellipse
        5、多边形 poly
    */

   /*
        1、Point 点x,y
        2、Size 尺寸 width height
        3、Rect 矩形 x,y,width,height
        4、Scalar 颜色
   */

    Mat m(600, 400, CV_8UC4);
    m.zeros(600, 400, CV_8UC4);
    
    /*
        Scalar 颜色对象,可以填写对应的颜色
        thickness 线的宽度  对于包围图形,-1代表填充内部空间
        Linettype 线的类型
    */
    line(m, Point(100, 100), Point(300, 500), Scalar(0, 0, 255, 128), 5, -1);

    rectangle(m, Point(100, 100), Point(300, 500), Scalar(0, 255, 0, 128), -1, LINE_4);

    circle(m, Point(100, 100), 50, Scalar(255, 0, 0, 128), -1, LINE_4);

    /*
        cvtColor
    */
   cvtColor(m, m, COLOR_BGR2BGRA, 4);

   /*
        如果是单信道channel,单独数值
        如果是多信道呢?
   */
  uchar signal_channel = m.at<uchar>(100, 100);
  Vec2b double_channel = m.at<Vec2d>(100, 100);
    
    imshow("result", m);

    waitKey(0);
    return 0;
}

tecnologia de processamento gráfico

Tecnologia de Transformação de Escala de Cinza de Imagem

Existem duas aplicações principais da tecnologia de transformação em escala de cinza

(1) Extraia informações importantes para processamento de contorno de imagem

(2) Otimize os detalhes para melhorar o efeito da imagem

Técnicas Comuns de Transformação em Tons de Cinza

(1) Processamento de limite

(2) Processamento de informações de histograma

(3) Função de transformação em tons de cinza

álgebra linear

transformação logarítmica

Correção gama

Uso abrangente (tecnologia de alongamento de contraste camadas em escala de cinza camadas de plano de bits)

(4) Transformação de distância

Limiar

Thresholding é a binarização do processamento de imagens. É o método mais simples de segmentação de imagens. A binarização converte uma imagem em tons de cinza em uma imagem binária. Defina a escala de cinza de pixels maior que um determinado valor crítico de escala de cinza como o valor máximo de escala de cinza e defina a escala de cinza de pixels menor que esse valor como o valor mínimo de escala de cinza, realizando assim a binarização.

Limiar comumente usado:

Limiar OTSU

limite fixo

limite adaptativo

limiarização dupla

meio limiar

Limiar OTSU

O algoritmo OTSU também é chamado de método da diferença máxima entre classes, às vezes chamado de algoritmo Otsu. Foi proposto por Otsu em 1979 e é considerado o melhor algoritmo para seleção de limites na segmentação de imagens.

Sua ideia básica é usar um limite para dividir os dados na imagem em duas categorias. A escala de cinza dos pixels na imagem em uma categoria é menor que o limite, e a escala de cinza dos pixels na imagem na outra categoria é maior ou igual ao limite. Em seguida, a imagem pode ser dividida em primeiro plano e plano de fundo usando o limiar. Em geral, extrair o primeiro plano pode obter o contorno da imagem que desejamos.

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;
//阈值计算
int my_otsu(Mat inputImg) {
    //初始化
    int rows = inputImg.rows;
    int cols = inputImg.cols;
    int sumPixel[256] = {0};
    float proDis[256] = {0};
    int result_threshold;
    //拿到灰度值的统计信息,统计一张图中的各个像素的出现的灰度值次数,比如在点(2,3)处的灰度值为100,而(20,20)处的灰度值也是100,那么就统计100出现两次
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            sumPixel[(int)inputImg.at<uchar>(i, j)]++;
            //cout << i << ":" << j << "->" << (int)inputImg.at<uchar>(i, j) << endl;
        }
    }
    //计算概率发布,某灰度值出现的次数占所有图所有像素的比例
    for (int i = 0; i < 256; i++) {
        proDis[i] = sumPixel[i] / (float)(rows * cols);
    }
    //计算最大方差
    float all_left, all_right, avg_left, avg_right, temp_left, temp_right, temp_delta;
    float max_delta = 0.0;
    for (int i = 0; i < 255; i++) {
        all_left = all_right = avg_left = avg_right = temp_left = temp_right = temp_delta = 0;
        for (int j = 0; j < 255; j++) {//把所有的灰度值分为左右两部分
            if (j <= i) {
                all_left += proDis[j];
                temp_left += j * proDis[j];
            } else {
                all_right += proDis[j];
                temp_right += j * proDis[j];
            }
        }
        //通过求出的左右两部分的所有占比然后就求平均值
        avg_left = temp_left / all_left;
        avg_right = temp_right / all_right;
        //求方差
        temp_delta = (float)(all_left * all_right * pow((avg_left - avg_right), 2));
        if (temp_delta > max_delta) {
            max_delta = temp_delta;
            result_threshold = i;
        }
    }

    //计算结果
    return result_threshold;
}

int main(int argc, char const *argv[])
{
    //读入图片
    Mat srcImg = imread("A:/OPENC/threshold/R-C.jpg");
    //转换为灰度图
    Mat grayImg;
    cvtColor(srcImg, grayImg, COLOR_RGB2GRAY);
    // imshow("src", srcImg);
    // imshow("gray", grayImg);
    //进行阈值计算
    int otsu = my_otsu(grayImg);
    cout << otsu << endl;
    //通过阈值进行二值化
    Mat result = grayImg.clone();
	
    //OTSU阈值化处理
    for (int i = 0; i < grayImg.rows; i++) {
        for (int j = 0; j < grayImg.cols; j++) {
            if (grayImg.at<uchar>(i , j) >= otsu) {
                result.at<uchar>(i, j) = 255;
            } else {
                result.at<uchar>(i, j) = 0;
            }
        }
    }
    imshow("result", result);
    //

    waitKey(0);
    return 0;
}

limite fixo

Função e método de cálculo de limite

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
    Mat srcImg = imread("A:/OPENC/threshold/R-C.jpg", IMREAD_GRAYSCALE);
    //根据填写阈值进行处理,根据输入的type类型阈值处理
    Mat resultImg;
    threshold(srcImg, resultImg, 138, 255, THRESH_BINARY);
    // THRESH_BINARY     = 0 二值化,超过阈值,保留为白色
    // THRESH_BINARY_INV = 1 反二值化,与上面的方式相反
    // THRESH_TRUNC      = 2 超过阈值的部分,保留到阈值
    // THRESH_TOZERO     = 3 不足阈值的部分,清0,超过阈值的部分,保留
    // THRESH_TOZERO_INV = 4 不足阈值保留,超过,清0
    //THRESH_MASK       = 7  一般用在抠图或则截取信息
    //THRESH_OTSU       = 8 是否使用OTSU算法
    //THRESH_TRIANGLE   = 16 
    imshow("src", srcImg);
    imshow("gray", resultImg);
    waitKey(0);
    
    return 0;
}

limite adaptativo
Mat adapImg;
    /*
        ADAPTIVE_THRESH_MEAN_C 平均计算
        ADAPTIVE_THRESH_GAUSSIAN_C 高斯算法, 计算当前值距离,通过高斯方程拿到结果
    */
    adaptiveThreshold(srcImg, adapImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 5, 2);
limiarização dupla
meio limiar
/*
    固定阈值,进行全局阈值处理,针对亮暗区分明显的使用办法
    自适应阈值,前后区分不明显,获取轮廓的方式
    双阈值化,通过大小阈值的两次操作,找到图片中的关键信息
    半阈值化,主要用于拿到图片中的诸如文字特征明显的信息
*/

Processamento de informações de histograma

Em estatística, um histograma é uma representação gráfica da distribuição de dados, é um gráfico estatístico bidimensional, cujas duas coordenadas são a amostra estatística e a medida de um determinado atributo correspondente à amostra.forma específica de expressão. Como o comprimento e a largura do histograma são muito adequados para expressar mudanças quantitativas, é mais fácil interpretar valores com pequenas diferenças

O histograma é um diagrama que pode ser usado para entender a distribuição dos tons de cinza de toda a imagem como um todo. Através do histograma, podemos ter uma compreensão intuitiva do contraste, brilho e distribuição dos tons de cinza da imagem.

Perceba os pixels da imagem de exibição do histograma:

#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    //灰度直方图 H-S直方图 RGB直方图
    Mat srcImg = imread("A:/OPENC/histogram/zhanyangsong.jpg");

    Mat grayImg;
    cvtColor(srcImg, grayImg, COLOR_RGB2GRAY);
    //计算直方图信息
    /*
        CV_EXPORTS void calcHist( const Mat* images, int nimages,
                          const int* channels, InputArray mask,
                          OutputArray hist, int dims, const int* histSize,
                          const float** ranges, bool uniform = true, bool accumulate = false );
        images 输入的图片组:图片需要拥有相同的大小,相同的颜色深度
        nimages 图像的个数
        channels 需要计算的直方图的通道个数
        mask 可选的掩码,一般不使用时设置为空。掩码图片必须和输入的图片组大小相同。
        hist 输出的直方图信息
        dima 直方图的维数
        histSize 直方图维度大小
        ranges 直方图统计的范围
        uniform 是否进行归一化处理
        accumulate 累计操作,默认不需要
    */
    int channels[1] = {0};
    Mat hist;
    int histSize[1] = {256};
    float hrange[2] = {0, 255};
    const float *ranges[1] = {hrange};
    calcHist(&grayImg, 1, channels, Mat(), hist, 1, histSize, ranges);
    
    //绘制直方图
    Mat histOutputImg(256, 256, CV_8U, Scalar(255));
    double maxValue;
    double minValue;
    minMaxLoc(hist, &minValue, &maxValue);
    int hpt = 0.9 * 256;
    for (int i = 0; i < 256; i++) {
        float binVal = hist.at<float>(i);
        int temp = (binVal * hpt / maxValue); 
        line(histOutputImg, Point(i, 256), Point(i, 256 - temp), Scalar::all(0));
    }

    imshow("srcImg", srcImg);
    imshow("grap", grayImg);
    imshow("result", histOutputImg);
    waitKey(0);
    return 0;
}

Operações comuns de histograma:

Equalização do histograma

Correspondência de histograma

Comparação de histograma

pesquisa de histograma

Histograma cumulativo

#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
#include <vector>
using namespace std;

Mat histOutputImg(Mat hist) {
    Mat histOutputImg(256, 256, CV_8U, Scalar(255));
    double maxValue;
    double minValue;
    minMaxLoc(hist, &minValue, &maxValue);
    int hpt = 0.9 * 256;
    for (int i = 0; i < 256; i++) {
        float binVal = hist.at<float>(i);
        int temp = (binVal * hpt / maxValue); 
        line(histOutputImg, Point(i, 256), Point(i, 256 - temp), Scalar::all(0));
    }
    return histOutputImg;
}



int main(int argc, char const *argv[])
{
    //灰度直方图 H-S直方图 RGB直方图
    Mat srcImg = imread("A:/OPENC/histogram/1.jpg");

    Mat grayImg;
    cvtColor(srcImg, grayImg, COLOR_RGB2GRAY);
    //计算直方图信息
    /*
        CV_EXPORTS void calcHist( const Mat* images, int nimages,
                          const int* channels, InputArray mask,
                          OutputArray hist, int dims, const int* histSize,
                          const float** ranges, bool uniform = true, bool accumulate = false );
        images 输入的图片组:图片需要拥有相同的大小,相同的颜色深度
        nimages 图像的个数
        channels 需要计算的直方图的通道个数
        mask 可选的掩码,一般不使用时设置为空。掩码图片必须和输入的图片组大小相同。
        hist 输出的直方图信息
        dima 直方图的维数
        histSize 直方图维度大小
        ranges 直方图统计的范围
        uniform 是否进行归一化处理
        accumulate 累计操作,默认不需要
    */
    int channels[1] = {0};
    Mat hist;
    int histSize[1] = {256};
    float hrange[2] = {0, 255};
    const float *ranges[1] = {hrange};
    calcHist(&grayImg, 1, channels, Mat(), hist, 1, histSize, ranges);


    //绘制直方图
    

    //直方图均衡化 将过亮或过暗的图片通过均衡化,细节暴露出来
    Mat equalizeOutImg;
    equalizeHist(grayImg, equalizeOutImg);
    Mat outHist;
    calcHist(&grayImg, 1, channels, Mat(), outHist, 1, histSize, ranges);
    //彩色图均衡化处理
    Mat colorImg;
    vector<Mat> BRG_channels;
    split(srcImg, BRG_channels);
    for (unsigned long i = 0; i < BRG_channels.size(); i++) {
        equalizeHist(BRG_channels[i], BRG_channels[i]);
    }
    merge(BRG_channels, colorImg);

    //直方图匹配:使两张匹配的图片的像素融合
    Mat newSrcImg = imread("A:/OPENC/histogram/zhanyangsong.jpg");
    Mat newGrayImg;
    cvtColor(newSrcImg, newGrayImg, COLOR_RGB2GRAY);
    Mat newHist;
    calcHist(&newGrayImg, 1, channels, Mat(), newHist, 1, histSize, ranges);
    //计算图片的累计概率
    float histOld[256] = {hist.at<float>(0)};
    float histNew[256] = {newHist.at<float>(0)};
    for (int i = 0; i < 256; i++) {
        histOld[i] = histOld[i - 1] + hist.at<float>(i);
        histNew[i] = histNew[i - 1] + newHist.at<float>(i);
    }
    //构建累计概率误差概率
    float diff[256][256];
    for (int i = 0; i < 256; i++) {
        for (int j = 0; j < 256; j++) {
            diff[i][j] = fabs(histOld[i] - histNew[j]);
        }
    }
    //生成LUT(lookuptable)表
    Mat Lut(1, 256, CV_8U);
    for (int i = 0; i < 256; i++) {
        float min = diff[i][0];
        int index = 0;
        for (int j = 0; j < 256; j++) {
            if (min > diff[i][j]) {
                min = diff[i][j];
                index = j;
            }
        }
        
        Lut.at<uchar>(i) = (uchar)index;
    }
    Mat resultOutImg, histOut;
    LUT(grayImg, Lut, resultOutImg);
    calcHist(&resultOutImg, 1, channels, Mat(), histOut, 1, histSize, ranges);

    //直方图对比
    for (int i = 0; i < 6; i++) {
        cout << compareHist(hist, newHist, i) << endl; 
    }

    //imshow("srcImg", srcImg);
    // imshow("grap", grayImg);
    // imshow("histImg", histOutputImg(hist));
    // imshow("result", histOutputImg(hist));
    // imshow("equalineOutImg", equalizeOutImg);
    //imshow("histImg", histOutputImg(outHist));
    //imshow("ColorImg", colorImg);
    // imshow("newSrcImg", newGrayImg);
    // imshow("newHist", histOutputImg(newHist));
    // imshow("outImg", resultOutImg);
    // imshow("histout", histOutputImg(histOut));
    waitKey(0);
    return 0;
}

Função de processamento de escala de cinza e sua aplicação

transformação linear

O brilho e o contraste de toda a imagem podem ser ajustados alterando o valor de um único pixel fazendo uma transformação linear, ou seja, realizando uma transformação linear no pixel, seja r o nível de cinza antes da transformação e s o nível de cinza após a transformação, então a função da transformação linear:

S = ar + b

Entre eles, a é a inclinação da linha e b é a interceptação no eixo y. A escolha de valores a e b diferentes terá efeitos diferentes:

a > 1, aumenta o contraste da imagem

a < 1, reduza o contraste da imagem

a = 0, b != 0, a imagem fica mais clara ou mais escura

a < 0 e b = 0, as áreas claras da imagem são escurecidas e as áreas escuras são iluminadas

a = -1, b = 255, inversão de brilho da imagem

Combate real do projeto (projetos são colocados em recursos)

Acho que você gosta

Origin blog.csdn.net/qq_58360406/article/details/129386236
Recomendado
Clasificación