Notas de Opencv-C++ (10): cálculo de píxeles de imagen opencv

1. Probabilidad

Podemos entender una imagen digital como una matriz de un tamaño determinado, el tamaño de cada elemento de la matriz representa el brillo y la oscuridad de cada píxel de la imagen, por lo tanto, el valor máximo en la matriz estadística es encontrar el píxel con el mayor valor de gris en la imagen. Calcular el valor promedio es calcular el nivel de gris promedio de los píxeles de la imagen, que se puede usar para representar el brillo y la oscuridad generales de la imagen. Por lo tanto, el trabajo estadístico para datos matriciales también tiene un cierto significado y papel en los píxeles de la imagen. En OpenCV 4, se integran funciones para calcular el valor máximo, el valor mínimo, el valor promedio, el error cuadrático medio y muchas otras estadísticas de los píxeles de la imagen. A continuación, se presentarán en detalle las funciones relacionadas con estas funciones.

2. Encuentra los valores máximo y mínimo de los píxeles de la imagen

void cv::minMaxLoc(InputArray src,
                   double * minVal,
                   double * maxVal = 0,
                   Point * minLoc = 0,
                   Point * maxLoc = 0,
                   InputArray mask = noArray())

src: La imagen o matriz que necesita encontrar los valores máximos y mínimos, debe ser una matriz de un solo canal
minVal: El valor mínimo en la imagen o matriz.
maxVal: El valor máximo en la imagen o matriz.
minLoc: Las coordenadas del valor mínimo en la imagen o matriz en la matriz.
maxLoc: Las coordenadas del valor máximo en la imagen o matriz en la matriz.
máscara: máscara, utilizada para establecer el área especificada en la imagen o matriz para encontrar el valor máximo.

Aquí vemos un nuevo tipo de datos Point, que se utiliza para representar las coordenadas de píxeles de la imagen. Dado que el eje de coordenadas de píxeles de la imagen toma la esquina superior izquierda como origen de coordenadas, la dirección horizontal es el eje x y la dirección vertical la dirección es el eje y, por lo que Point (x,y) corresponde a las filas y columnas de la imagen expresada como Point(columns, rows). En OpenCV, se configura una variedad de tipos de datos tanto para coordenadas 2D como para coordenadas 3D. Para los tipos de datos de coordenadas 2D, las coordenadas enteras cv::Point2i (o cv::Point), las coordenadas dobles cv::Point2d y los tipos de punto flotante son La coordenada cv::Point2f también define el tipo de datos de coordenadas mencionado anteriormente para coordenadas 3D, y solo necesita cambiar el número "2" a "3". Para los datos específicos de los ejes x, y y z en las coordenadas, se puede acceder a ellos a través de los atributos de las variables x, y y z. Por ejemplo, Point.x puede leer los datos del eje x de las coordenadas .

La función que realiza esta función es encontrar el valor máximo en un área específica de la imagen. El primer parámetro de la función es ingresar una matriz de un solo canal. Cabe señalar que esta variable debe ser una matriz de datos de un solo canal. Si se trata de una matriz de datos multicanal, debe usar cv::Mat::reshape() para cambiar múltiples canales en un solo canal, o encontrar el valor máximo de cada canal por separado y luego comparar para encontrar el global. valor máximo. Para el uso de cv::Mat::reshape(), se proporciona en el listado de código 3-8. Los parámetros del segundo al quinto son punteros al valor mínimo, valor máximo, posición de valor mínimo y posición de valor máximo respectivamente. Si no necesita encontrar un determinado parámetro, puede establecer este parámetro en NULL. El último parámetro de la función es para encontrar el más valioso La matriz de máscara se usa para marcar el rango para buscar los cuatro valores anteriores. El valor predeterminado del parámetro es noArray(), lo que significa que el rango de búsqueda son todos los datos en la matriz.

Mat cv::Mat::reshape(int  cn,int  rows = 0)

cn: el número de canales de la matriz transformada.
filas: el número de filas de la matriz después de la transformación, si el parámetro es cero, el número de filas después de la transformación es el mismo que antes de la transformación.

Tenga en cuenta que
si hay varios valores máximos o mínimos en la matriz, la posición en la que la función minMaxLoc() genera el valor máximo es la posición en la que se detecta el valor máximo por primera vez mediante el escaneo de filas de izquierda a derecha. Al mismo tiempo, al ingresar parámetros, asegúrese de agregar el carácter de dirección de valor.
Para que los lectores comprendan mejor el principio y el uso de la función minMaxLoc(), en el Listado de Código 3-9 se proporciona un programa de muestra para encontrar el valor máximo de la matriz, y se muestra el resultado final de la operación del programa. en la Figura 3-6 y en la Figura 3-7 se muestra el contenido de las dos matrices creadas y las matrices transformadas por canal vistas en Image
Watch.

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    
    
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    float a[12]={
    
    1,2,3,4,5,10,6,7,8,9,10,0};
    Mat img=Mat(3,4,CV_32FC1,a);//单通道矩阵
    Mat imgs=Mat(2,3,CV_32FC2,a);//多通道矩阵
    double minVal,maxVal;//用于存放矩阵中的最大值和最小值
    Point minIdx,maxIdx;//用于存放矩阵中的最大值和最小值的位置

    /*寻找单通道矩阵中的最值*/
    minMaxLoc(img,&maxVal,&minVal,&minIdx,&maxIdx);
    cout << "img中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl;
    cout << "img中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl;

    /*寻找多通道矩阵中的最值*/
    Mat imgs_re=imgs.reshape(1,4);//将多通道矩阵变成单通道矩阵
    minMaxLoc(imgs_re,&minVal,&maxVal,&minIdx,&maxIdx);
    cout << "img中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl;
    cout << "img中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl;
    return 0;
}

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3. Calcular la desviación media y estándar de la imagen

El valor medio de la imagen indica el brillo y la oscuridad generales de la imagen, y cuanto mayor sea el valor medio de la imagen, más brillante será la imagen en su conjunto. La desviación estándar representa el grado de contraste de los cambios de luz y oscuridad en la imagen, y cuanto mayor es la desviación estándar, más evidentes son los cambios de luz y oscuridad en la imagen. OpenCV
4 proporciona la función mean() para calcular el valor medio de la imagen y la función meanStdDev() para calcular la media y la desviación estándar de la imagen al mismo tiempo. A continuación, presentaremos cómo usar estas dos funciones en detalle.

cv::Scalar cv::mean(InputArray src,InputArray mask = noArray())

src: La matriz de la imagen a promediar.
máscara: máscara, que se utiliza para marcar qué áreas se promedian.

Esta función se usa para calcular el valor promedio de cada canal de la matriz de imagen. El primer parámetro de la función se usa para ingresar la matriz de imagen a promediar. El número de canales puede estar entre 1 y 4. Cabe señalar que el valor de retorno de esta función es una variable de tipo cv::Scalar. El valor de retorno de la función tiene 4 bits, que representan respectivamente el valor promedio de los 4 canales de la imagen de entrada. Si la imagen de entrada tiene solo 1 canal, entonces el valor de retorno Los últimos tres bits son todos 0. Por ejemplo, si ingresa una imagen con un valor promedio de un solo canal de 1 en esta función, el resultado de salida es [1,0,0,0 ], y puede ver el canal n a través de cv::Scalar[n] promedio de. El segundo parámetro de esta función se usa para controlar el rango de cálculo del valor medio de la imagen. En el primer parámetro, se elimina el píxel con un valor de píxel de 0 en el segundo parámetro. El principio de cálculo se muestra en la fórmula (3.5 Cuando no se ingresa Cuando se usa el segundo parámetro, significa calcular el valor promedio de todos los píxeles del primer parámetro.
inserte la descripción de la imagen aquí
Entre ellos, representa el valor medio del canal c-ésimo y representa el valor de gris del píxel del canal c-ésimo.
La función meanStdDev() puede calcular el valor medio y la desviación estándar de cada canal de la imagen al mismo tiempo, y su prototipo de función se proporciona en el Listado de Código 3-11.

void cv::meanStdDev(InputArray src,OutputArray mean,OutputArray stddev,InputArray mask = noArray())
src:待求平均值的图像矩阵。
mean:图像每个通道的平均值,参数为Mat类型变量。
stddev:图像每个通道的标准方差,参数为Mat类型变量。
mask:掩模,用于标记求取哪些区域的平均值和标准方差。

El primer parámetro de esta función es el mismo que el primer parámetro de la función mean() anterior, que puede ser una imagen de 1 a 4 canales. La diferencia es que esta función no tiene valor de retorno, y la media y la desviación estándar de la imagen se emiten en la primera función. En el segundo y tercer parámetro, a diferencia de la función mean(), la variable tipo Mat se utiliza para almacenar el valor medio y la desviación estándar. El número de datos en la variable es el mismo que el número de canales en el primer parámetro.Si la imagen de entrada tiene solo un canal, solo hay un dato en las variables media y desviación estándar calculadas por esta función. El principio de cálculo de esta función se muestra en la fórmula (3.6).

inserte la descripción de la imagen aquí

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    
    
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    float a[12]={
    
    1,2,3,4,5,10,6,7,8,9,10,0};
    Mat img=Mat(3,4,CV_32FC1,a);//单通道矩阵
    Mat imgs=Mat(2,3,CV_32FC2,a);//多通道矩阵

    cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl;
    Scalar myMean;
    myMean=mean(imgs);
    cout<<"imgs均值 = "<<myMean<<endl;
    cout<<"imgs第一个通道的均值 = "<<myMean[0]<<" "
        <<"imgs第二个通道的均值 = "<<myMean[1]<<endl;

    cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl;
    Mat myMeanMat,myStddevMat;

    meanStdDev(img,myMeanMat,myStddevMat);
    cout << "img均值=" << myMeanMat << " " << endl;
    cout << "img标准方差=" << myStddevMat << endl << endl;
    meanStdDev(imgs,myMeanMat,myStddevMat);
    cout << "img均值=" << myMeanMat << " " << endl;
    cout << "img标准方差=" << myStddevMat << endl << endl;
    return 0;
}

inserte la descripción de la imagen aquí

4. Operación de comparación de dos imágenes.

OpenCV 4 proporciona las funciones max() y min() para calcular el valor de gris más grande o más pequeño de cada píxel en dos imágenes. Estas dos funciones comparan el valor de gris de cada elemento en las dos imágenes, respectivamente. valores en escala de grises

 void cv::max(InputArray src1,InputArray src2,OutputArray dst) void
 cv::min(InputArray src1,InputArray src2,OutputArray dst)
  • src1: la primera matriz de imagen, que puede ser una matriz con cualquier número de canales.
  • src2: la segunda matriz de imagen, el tamaño, la cantidad de canales y el tipo de datos deben ser coherentes con src1.
  • dst: la matriz de imagen después de retener el valor de gris más grande (más pequeño) de la posición correspondiente, el tamaño, la cantidad de canales y el tipo de datos son consistentes con src1.

La función de esta función es relativamente simple, que consiste en comparar el tamaño de cada píxel de la imagen, retener el valor mayor o menor según se requiera y finalmente generar una nueva imagen. Por ejemplo, si el valor de píxel de la primera imagen es 100 y el valor de píxel de la segunda imagen es 10, entonces el valor de píxel de la imagen de salida es 100. El proceso de implementación del código y los resultados de la operación de estas dos funciones se proporcionan en el Listado de Código 3-14, y los resultados de la operación se muestran en la Figura 3-9, la Figura 3-10 y la Figura 3-11. Esta operación de comparación se utiliza principalmente en el procesamiento de datos de tipo matriz, y la operación de comparación con la imagen de máscara puede lograr el efecto de matizar o seleccionar canales.

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    
    
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    float a[12]={
    
    1,2,3.3,4,5,9,5,7,8.2,9,10,2};
    float b[12]={
    
    1,2.2,3,1,3,10,6,7,8,9.3,10,1};
    Mat imga=Mat(3,4,CV_32FC1,a);
    Mat imgb=Mat(3,4,CV_32FC1,b);
    Mat imgas=Mat(2,3,CV_32FC2,a);
    Mat imgbs=Mat(2,3,CV_32FC2,b);

    //对两个单通道矩阵进行比较远算
    Mat myMax,myMin;
    max(imga,imgb,myMax);
    min(imga,imgb,myMin);

    //对两个多通道矩阵进行比较运算
    Mat myMaxs,myMins;
    max(imgas,imgbs,myMaxs);
    min(imgas,imgbs,myMins);

    //对两张彩色图像进行比较运算
    Mat img0=imread("lena.png");
    Mat img1=imread("noobcv.jpg");
    if(img0.empty()||img1.empty()){
    
    
        cout<<"请确认图像文件名称是否正确"<<endl;
        return -1;
    }
    Mat comMin,comMax;
    max(img0,img1,comMax);
    min(img0,img1,comMin);
    imshow("comMin",comMin);
    imshow("comMax",comMax);

    //与掩模进行比较运算
    Mat src1=Mat::zeros(Size(512,512),CV_8UC3);
    Rect rect(100,100,300,300);
    src1(rect)=Scalar(255,255,255);//生成一个300*300的掩模
    Mat comsrc1,comsrc2;
    min(img0,src1,comsrc1);
    imshow("comsrc1",comsrc1);

    Mat src2=Mat(512,512,CV_8UC3,Scalar(0,0,255));//生成一个显示红色的低通掩模
    min(img0,src2,comsrc2);
    imshow("comsrc2",comsrc2);

    //对两张图片灰度图像进行比较运算
    Mat img0G,img1G,comMinG,comMaxG;
    cvtColor(img0,img0G,COLOR_BGR2GRAY);
    cvtColor(img1,img1G,COLOR_BGR2GRAY);
    max(img0G,img1G,comMaxG);
    max(img0G,img1G,comMaxG);
    imshow("comMinG",comMinG);
    imshow("comMaxG",comMaxG);
    return 0;
}

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

5. Operación lógica de dos imágenes.

OpenCV 4 proporciona cuatro funciones **bitwise_and(), bitwise_or(), bitwise_xor() y bitwise_not()** para operaciones AND, OR, XOR y NOT entre dos píxeles de imagen, en el listado de código 3-15 Los prototipos de funciones de estos cuatro Las funciones se dan en . Antes de comprender el uso de las funciones, comprendamos las reglas de operación lógica de los píxeles de la imagen. La operación lógica entre píxeles de imagen es la misma que la operación lógica entre números, y las reglas específicas se dan en la Figura 3-12. La operación de negación de un píxel solo se puede realizar en un valor, por lo que la operación de negación se realiza en el valor de píxel de la imagen 1 cuando se niega el píxel en la Figura 3-12. Si el valor de píxel es solo 0 y 1, entonces las primeras 4 filas de datos en la figura corresponden a todas las reglas de operación, pero el valor de píxel de la imagen del tipo CV_8U es de 0 a 255, y la operación lógica en este momento necesita convierta el valor del píxel para convertirlo en un número binario, porque el tipo CV_8U son datos de 8 bits, por lo que negar 0 es 11111111, que es 255. En la última fila de datos de la Figura 3-12, el valor binario correspondiente al valor de píxel 5 es 101 y el valor binario correspondiente al valor de píxel 6 es 110, por lo que la operación AND es 100 (4) o la operación es 111 (7), y la operación XOR es 011 (3), niega el valor de píxel 5 para obtener 11111010 (250). Después de comprender el principio de la operación de matriz de píxeles, veamos
cómo usar la función de operación de matriz proporcionada en OpenCV 4.
inserte la descripción de la imagen aquí

//像素求与运算
  void cv::bitwise_and(InputArray src1,
                           InputArray src2,
                           OutputArray dst,
                          InputArray mask = noArray()
                            )
  //像素求或运算
   void cv::bitwise_or(InputArray src1,
                     InputArray src2,
                      OutputArray dst,
                      InputArray mask = noArray()
                        )
   //像素求异或运算
   void cv::bitwise_xor(InputArray src1,
                       InputArray src2,
                       OutputArray dst,
                       InputArray mask = noArray()
                        )
   //像素求非运算
   void cv::bitwise_not(InputArray src,
                       OutputArray dst,
                       InputArray mask = noArray()
                         )
  • src1: la primera matriz de imagen, que puede ser datos de imagen multicanal.
  • src2: la segunda matriz de imagen, el tamaño, la cantidad de canales y el tipo de datos deben ser coherentes con src1.
  • dst: el resultado de salida de la operación lógica, el tamaño, la cantidad de canales y el tipo de datos son consistentes con src1.
  • máscara: máscara, utilizada para establecer el rango de operaciones lógicas en imágenes o matrices.

Todas estas funciones realizan operaciones lógicas correspondientes. Al realizar cálculos lógicos, es necesario asegurarse de que el tamaño, el tipo de datos y la cantidad de canales entre las dos matrices de imagen sean iguales. Cuando varios canales realizan operaciones lógicas, los diferentes canales se realizan de forma independiente de Para comprender la operación lógica entre dos píxeles de imagen de manera más intuitiva, en el Listado de Código 3-16 se proporciona un programa de ejemplo para la operación lógica de dos píxeles de imagen en blanco y negro.

#include <opencv2\opencv.hpp>
   2.  #include <iostream>
   3.  #include <vector>
   4.  
   5.  using namespace std;
   6.  using namespace cv;
   7.  
   8.  int main()
   9. {
    
    
   10.    Mat img = imread("lena.png");
   11.    if (img.empty())
   12.    {
    
    
   13.      cout << "请确认图像文件名称是否正确" << endl;
   14.      return -1;
   15.    }
   16.    //创建两个黑白图像
   17.    Mat img0 = Mat::zeros(200, 200, CV_8UC1);
   18.    Mat img1 = Mat::zeros(200, 200, CV_8UC1);
   19.    Rect rect0(50, 50, 100, 100);
   20.    img0(rect0) = Scalar(255);
   21.    Rect rect1(100, 100, 100, 100);
   22.    img1(rect1) = Scalar(255);
   23.    imshow("img0", img0);
   24.    imshow("img1", img1);
   25.  
   26.    //进行逻辑运算
   27.    Mat myAnd, myOr, myXor, myNot, imgNot;
   28.    bitwise_not(img0, myNot);
   29.    bitwise_and(img0, img1, myAnd);
   30.    bitwise_or(img0, img1, myOr);
   31.    bitwise_xor(img0, img1, myXor);
   32.    bitwise_not(img, imgNot);
   33.    imshow("myAnd", myAnd);
   34.    imshow("myOr", myOr);
   35.    imshow("myXor", myXor);
   36.    imshow("myNot", myNot);
   37.    imshow("img", img);
   38.    imshow("imgNot", imgNot);
   39.    waitKey(0);
   40.    return 0;
   41.  }

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/jiyanghao19/article/details/131251381
Recomendado
Clasificación