灰度共生矩阵的原理及实现(特征提取)-OpenCV

2023-11-09


最近在研究机器学习相关内容,后面会尽量花时间整理成一个系列的博客,然后朋友让我帮他实现一种基于SVR支持向量回归的图像质量评价方法,然而在文章的开头竟然发现
灰度共生矩阵这个陌生的家伙,于是便有此文。

这里写图片描述

主要参考博客1:http://blog.csdn.net/jialeheyeshu/article/details/51337225
主要参考博客2:http://blog.csdn.net/guanyuqiu/article/details/53117507
主要参考博客3:http://www.cnblogs.com/rong86/p/3695621.html
主要参考博客4:http://blog.csdn.net/lingtianyulong/article/details/53032034

1.灰度共生矩阵生成原理
  灰度共生矩阵(GLDM)的统计方法是20世纪70年代初由R.Haralick等人提出的,它是在假定图像中各像素间的空间分布关系包含了图像纹理信息的前提下,提出的具有广泛性的纹理分析方法。

   灰度共生矩阵被定义为从灰度为i的像素点出发,离开某个固定位置(相隔距离为d,方位为)的点上灰度值为的概率,即,所有估计的值可以表示成一个矩阵的形式,以此被称为灰度共生矩阵。对于纹理变化缓慢的图像,其灰度共生矩阵对角线上的数值较大;而对于纹理变化较快的图像,其灰度共生矩阵对角线上的数值较小,对角线两侧的值较大。由于灰度共生矩阵的数据量较大,一般不直接作为区分纹理的特征,而是基于它构建的一些统计量作为纹理分类特征。Haralick曾提出了14种基于灰度共生矩阵计算出来的统计量:即:能量、熵、对比度、均匀性、相关性、方差、和平均、和方差、和熵、差方差、差平均、差熵、相关信息测度以及最大相关系数。

  在网上看了很多灰度共生矩阵生成的例子感觉都没有说明白,要不就直接上结果要不就给一堆看不懂的代码和公式,后来看了matlab中的介绍就明白了,其实很简单,仔细把下面的看三遍就理解怎么来的了!(我是第三篇看明白的,当时很紧张,相信你们没问题)
  下图显示了如何求解灰度共生矩阵,以(1,1)点为例,GLCM(1,1)值为1说明只有一对灰度为1的像素水平相邻。GLCM(1,2)值为2,是因为有两对灰度为1和2的像素水平相邻。(MatLab说明文档)
这里写图片描述

GLCM表其实就是所有像素可能的组合,比如,GLCM(1,1)就是I中像素值为1和1的组合,GLCM(4,5)就是I中像素4和像素5的组合,GLCM(i,j)的值呢就是I中像素为i,像素为j的有有多少和相邻的成对点。这个相邻有个规则:就是f(x,y),f(x+a,y+b)相邻,就是只有x相隔a的单位,y相隔b个单位,我们认为是相邻的。
平时我们说相邻:B点在A点右边,其实就是这里的a=1,b=0,也就是f(x,y)和f(x+1,y+0)相邻。
于是就有了:
a=1,b=0 时我们就说水平相邻:也就是0度的时候
a=1,b=1 时我们就说对角相邻,也就是45度的时候
a=-1,b=1时 即135度
其他角度类似。
在a=1,b=0时:GLCM(1,1)=1;其实就是I中有几个1和1相邻(1个)(按上面的规则)GLCM(1,2)=2,几个1和2相邻(2个)。ok!
后面好多的性质,都是在把这个矩阵计算出来之后再在这个基础上运算的,那些就不难了!

附加理解2:
共生矩阵用两个位置的像素的联合概率密度来定义,它不仅反映亮度的分布特征,也反映具有同样亮度或者接近亮度的像素之间的位置分布特性,是有关图像亮度变化的二阶统计特征。它是定义一组纹理特征的基础。

由于纹理是由灰度在空间位置上反复出现而形成的,因而在图像空间中像个某距离的两像素之间会存在一定的灰度关系,即图像中灰度的空间相关特性。灰度共生矩阵就是一种通过研究灰度的空间相关特性来描述纹理的常用方法。

灰度直方图是对图像上单个像素具有某个灰度进行统计的结果,

而灰度共生矩阵是对图像上保持某距离的两像素分别具有某灰度的状况进行统计得到的。

取图像(N×N)中任意一点 (x,y)及偏离它的另一点 (x+a,y+b),设该点对的灰度值为(g1,g2)。令点(x,y) 在整个画面上移动,则会得到各种 (g1,g2)值,设灰度值的级数为 k,则(g1,g2) 的组合共有 k^2;种。对于整个画面,统计出每一种(g1,g2)值出现的次数,然后排列成一个方阵,在用(g1,g2) 出现的总次数将它们归一化为出现的概率P(g1,g2),这样的方阵称为灰度共生矩阵。距离差分值(a,b) 取不同的数值组合,可以得到不同情况下的联合概率矩阵。(a,b)取值要根据纹理周期分布的特性来选择,对于较细的纹理,选取(1,0)、(1,1)、(2,0)等小的差分值。  当 a=1,b=0时,像素对是水平的,即0度扫描;当a=0,b=1 时,像素对是垂直的,即90度扫描;当 a=1,b=1时,像素对是右对角线的,即45度扫描;当 a=-1,b=-1时,像素对是左对角线,即135度扫描。
这样,两个象素灰度级同时发生的概率,就将 (x,y)的空间坐标转化为“灰度对” (g1,g2)的描述,形成了灰度共生矩阵。(百度百科)
一幅图象的灰度共生矩阵能反映出图象灰度关于方向、相邻间隔、变化幅度的综合信息,它是分析图象的局部模式和它们排列规则的基础。

感觉差不多了吧!

2.灰度共生矩阵特征量(字写的不好,请见谅)

(上述公式的来源要仔细推敲一番,在这里我的目的主要不是这个,所以咩有很详细的写出来,欢迎交流留言)

3.Code

GLCM.h


#include<iostream>
#include <cassert>
#include <vector>
#include <iterator>
#include <functional>
#include <algorithm>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

typedef vector<vector<int> > VecGLCM;

typedef struct _GLCMFeatures
{
    _GLCMFeatures()
        : energy(0.0)
        , entropy(0.0)
        , contrast(0.0)
        , idMoment(0.0)
    {

    }

    double energy;      // 能量 
    double entropy;     // 熵
    double contrast;    // 对比度
    double idMoment;    // 逆差分矩, inverse difference moment

} GLCMFeatures;

class GLCM
{
public:
    GLCM();
    ~GLCM();

public:
    // 枚举灰度共生矩阵的方向
    enum 
    {
        GLCM_HORIZATION = 0,        // 水平
        GLCM_VERTICAL = 1,          // 垂直
        GLCM_ANGLE45 = 2,           // 45度角
        GLCM_ANGLE135 = 3           // 135度角
    };

public:
    // 计算灰度共生矩阵
    void calGLCM(IplImage* inputImg, VecGLCM& vecGLCM, int angle);
    // 计算特征值
    void getGLCMFeatures(VecGLCM& vecGLCM, GLCMFeatures& features);
public:
    // 初始化灰度共生矩阵
    void initGLCM(VecGLCM& vecGLCM, int size = 16);
    // 设置灰度划分等级,默认值为 16
    void setGrayLevel(int grayLevel) { m_grayLevel = grayLevel; }
    // 获取灰度等级
    int getGrayLevel() const { return m_grayLevel; }
private:
    // 计算水平灰度共生矩阵
    void getHorisonGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);
    // 计算垂直灰度共生矩阵
    void getVertialGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);
    // 计算 45 度灰度共生矩阵
    void getGLCM45(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);
    // 计算 135 度灰度共生矩阵
    void getGLCM135(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight);

private:
    int m_grayLevel;        // 将灰度共生矩阵划分为 grayLevel 个等级

};

GLCM.cpp

#include "GLCM.h"

GLCM::GLCM() : m_grayLevel(16)
{

}

GLCM::~GLCM()
{

}

//==============================================================================
// 函数名称: initGLCM
// 参数说明: vecGLCM,要进行初始化的共生矩阵,为二维方阵
//          size, 二维矩阵的大小,必须与图像划分的灰度等级相等
// 函数功能: 初始化二维矩阵
//==============================================================================

void GLCM::initGLCM(VecGLCM& vecGLCM, int size)
{
    assert(size == m_grayLevel);
    vecGLCM.resize(size);
    for (int i = 0; i < size; ++i)
    {
        vecGLCM[i].resize(size);
    }

    for (int i = 0; i < size; ++i)
    {
        for (int j = 0; j < size; ++j)
        {
            vecGLCM[i][j] = 0;
        }
    }
}

//==============================================================================
// 函数名称: getHorisonGLCM
// 参数说明: src,要进行处理的矩阵,源数据
//          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
//          imgWidth, 图像宽度
//          imgHeight, 图像高度
// 函数功能: 计算水平方向的灰度共生矩阵
//==============================================================================

void GLCM::getHorisonGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight)
{
    int height = imgHeight;
    int width = imgWidth;

    for (int i = 0; i < height; ++i)
    {
        for (int j = 0; j < width - 1; ++j)
        {
            int rows = src[i][j];
            int cols = src[i][j + 1];
            dst[rows][cols]++;
        }
    }


}

//==============================================================================
// 函数名称: getVertialGLCM
// 参数说明: src,要进行处理的矩阵,源数据
//          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
//          imgWidth, 图像宽度
//          imgHeight, 图像高度
// 函数功能: 计算垂直方向的灰度共生矩阵
//==============================================================================

void GLCM::getVertialGLCM(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight)
{
    int height = imgHeight;
    int width = imgWidth;
    for (int i = 0; i < height - 1; ++i)
    {
        for (int j = 0; j < width; ++j)
        {
            int rows = src[i][j];
            int cols = src[i + 1][j];
            dst[rows][cols]++;
        }
    }
}

//==============================================================================
// 函数名称: getGLCM45
// 参数说明: src,要进行处理的矩阵,源数据
//          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
//          imgWidth, 图像宽度
//          imgHeight, 图像高度
// 函数功能: 计算45度的灰度共生矩阵
//==============================================================================

void GLCM::getGLCM45(VecGLCM &src, VecGLCM &dst, int imgWidth, int imgHeight)
{
    int height = imgHeight;
    int width = imgWidth;
    for (int i = 0; i < height - 1; ++i)
    {
        for (int j = 0; j < width - 1; ++j)
        {
            int rows = src[i][j];
            int cols = src[i + 1][j + 1];
            dst[rows][cols]++;
        }
    }
}


//==============================================================================
// 函数名称: getGLCM135
// 参数说明: src,要进行处理的矩阵,源数据
//          dst,输出矩阵,计算后的矩阵,即要求的灰度共生矩阵
//          imgWidth, 图像宽度
//          imgHeight, 图像高度
// 函数功能: 计算 135 度的灰度共生矩阵
//==============================================================================

void GLCM::getGLCM135(VecGLCM& src, VecGLCM& dst, int imgWidth, int imgHeight)
{
    int height = imgHeight;
    int width = imgWidth;
    for (int i = 0; i < height - 1; ++i)
    {
        for (int j = 1; j < width; ++j)
        {
            int rows = src[i][j];
            int cols = src[i + 1][j - 1];
            dst[rows][cols]++;
        }
    }
}

//==============================================================================
// 函数名称: calGLCM
// 参数说明: inputImg,要进行纹理特征计算的图像,为灰度图像
//          vecGLCM, 输出矩阵,根据灰度图像计算出的灰度共生阵
//          angle,灰度共生矩阵的方向,有水平、垂直、45度、135度四个方向
// 函数功能: 计算灰度共生矩阵
//==============================================================================

void GLCM::calGLCM(IplImage* inputImg, VecGLCM& vecGLCM, int angle)
{
    assert(inputImg->nChannels == 1);
    IplImage* src = NULL;
    src = cvCreateImage(cvGetSize(inputImg), IPL_DEPTH_32S, inputImg->nChannels);
    cvConvert(inputImg, src);

    int height = src->height;
    int width = src->width;
    int maxGrayLevel = 0;
    // 寻找最大像素灰度最大值
    for (int i = 0; i < height; ++i)
    {
        for (int j = 0; j < width; ++j)
        {
            int grayVal = cvGetReal2D(src, i, j);
            if (grayVal > maxGrayLevel)
            {
                maxGrayLevel = grayVal;
            }

        }
    }// end for i

    ++maxGrayLevel;
    VecGLCM tempVec;
    // 初始化动态数组
    tempVec.resize(height);
    for (int i = 0; i < height; ++i)
    {
        tempVec[i].resize(width);
    }

    if (maxGrayLevel > 16)//若灰度级数大于16,则将图像的灰度级缩小至16级,减小灰度共生矩阵的大小。
    {
        for (int i = 0; i < height; ++i)
        {
            for (int j = 0; j < width; ++j)
            {
                int tmpVal = cvGetReal2D(src, i, j);
                tmpVal /= m_grayLevel;
                tempVec[i][j] = tmpVal;
            }
        }

        if (angle == GLCM_HORIZATION)  // 水平方向
            getHorisonGLCM(tempVec, vecGLCM, width, height);
        if (angle == GLCM_VERTICAL)    // 垂直方向
            getVertialGLCM(tempVec, vecGLCM, width, height);
        if (angle == GLCM_ANGLE45)     // 45 度灰度共生阵
            getGLCM45(tempVec, vecGLCM, width, height);
        if (angle == GLCM_ANGLE135)    // 135 度灰度共生阵
            getGLCM135(tempVec, vecGLCM, width, height);
    }
    else//若灰度级数小于16,则生成相应的灰度共生矩阵
    {
        for (int i = 0; i < height; ++i)
        {
            for (int j = 1; j < width; ++j)
            {
                int tmpVal = cvGetReal2D(src, i, j);
                tempVec[i][j] = tmpVal;
            }
        }

        if (angle == GLCM_HORIZATION)  // 水平方向
            getHorisonGLCM(tempVec, vecGLCM, width, height);
        if (angle == GLCM_VERTICAL)    // 垂直方向
            getVertialGLCM(tempVec, vecGLCM, width, height);
        if (angle == GLCM_ANGLE45)     // 45 度灰度共生阵
            getGLCM45(tempVec, vecGLCM, width, height);
        if (angle == GLCM_ANGLE135)    // 135 度灰度共生阵
            getGLCM135(tempVec, vecGLCM, width, height);
    }

    cvReleaseImage(&src);
}

//==============================================================================
// 函数名称: getGLCMFeatures
// 参数说明: vecGLCM, 输入矩阵,灰度共生阵
//          features,灰度共生矩阵计算的特征值,主要包含了能量、熵、对比度、逆差分矩
// 函数功能: 根据灰度共生矩阵计算的特征值
//==============================================================================

void GLCM::getGLCMFeatures(VecGLCM& vecGLCM, GLCMFeatures& features)
{
    int total = 0;

    for (int i = 0; i < m_grayLevel; ++i)
    {
        for (int j = 0; j < m_grayLevel; ++j)
        {
            total += vecGLCM[i][j];     // 求所有图像的灰度值的和
        }
    }

    vector<vector<double> > temp;
    temp.resize(m_grayLevel);
    for (int i = 0; i < m_grayLevel; ++i)
    {
        temp[i].resize(m_grayLevel);
    }

    // 归一化
    for (int i = 0; i < m_grayLevel; ++i)
    {
        for (int j = 0; j < m_grayLevel; ++j)
        {
            temp[i][j] = (double)vecGLCM[i][j] / (double)total;
        }
    }

    for (int i = 0; i < m_grayLevel; ++i)
    {
        for (int j = 0; j < m_grayLevel; ++j)
        {
            features.energy += temp[i][j] * temp[i][j];

            if (temp[i][j]>0)
                features.entropy -= temp[i][j] * log(temp[i][j]);               //熵     

            features.contrast += (double)(i - j)*(double)(i - j)*temp[i][j];        //对比度
            features.idMoment += temp[i][j] / (1 + (double)(i - j)*(double)(i - j));//逆差矩
        }
    }
}

main.cpp

#include "GLCM.h"
#include <string>

void getFileName();
string names[2000];
char data[20];
const string filename = "C:\\Users\\ltc\\Desktop\\data5\\Sobel\\数值处理\\背景\\";

int main()
{
    fstream finout1("data.txt", ios::in | ios::out|ios::trunc);
    getFileName();
    int i = 0;
    char data1[20];
    while (names[i].length() > 5){
        strcpy_s(data1, names[i].c_str());
        string imagename = data1;
        //灰度共生矩阵
        IplImage* img = cvLoadImage(data1, 0);
        cvSetImageROI(img, cvRect(1453, 1149,557, 557));
        /*cvNamedWindow("ShowSRC"); 
        cvShowImage("ShowSRC",img); 
        cvWaitKey(0);  */

        GLCM glcm;
        VecGLCM vec;
        GLCMFeatures features;
        glcm.initGLCM(vec);
        // 水平
        glcm.calGLCM(img, vec, GLCM::GLCM_HORIZATION);
        glcm.getGLCMFeatures(vec, features);
        double energy_hor = features.energy;
        double entropy_hor = features.entropy;
        double contrast_hor = features.contrast;
        double idMoment_hor = features.idMoment;

        // 垂直
        glcm.calGLCM(img, vec, GLCM::GLCM_VERTICAL);
        glcm.getGLCMFeatures(vec, features);
        double energy_vetical = features.energy;
        double entropy_vetical = features.entropy;
        double contrast_vetical = features.contrast;
        double idMoment_vetical = features.idMoment;


        // 45 度
        glcm.calGLCM(img, vec, GLCM::GLCM_ANGLE45);
        glcm.getGLCMFeatures(vec, features);
        double energy_45 = features.energy;
        double entropy_45 = features.entropy;
        double contrast_45 = features.contrast;
        double idMoment_45 = features.idMoment;


        // 135 度
        glcm.calGLCM(img, vec, GLCM::GLCM_ANGLE135);
        glcm.getGLCMFeatures(vec, features);
        double energy_135 = features.energy;
        double entropy_135 = features.entropy;
        double contrast_135 = features.contrast;
        double idMoment_135 = features.idMoment;

        double energy_average = (energy_135 + energy_45 + energy_hor + energy_vetical) / 4;
        double entropy_average = (entropy_135 + entropy_45 + entropy_hor + entropy_vetical) / 4;
        double contrast_average = (contrast_135 + contrast_45 + contrast_hor + contrast_vetical) / 4;
        double idMoment_average = (idMoment_135 + idMoment_45 + idMoment_hor + idMoment_vetical) / 4;


        cout<< energy_average<<"  " <<entropy_average <<"  "<< contrast_average<<"  " << idMoment_average << endl;
        finout1 << energy_average<<"  " <<entropy_average <<"  "<< contrast_average<<"  " << idMoment_average << endl;
        i++;
    }
    system("pause");
    return 0;
}

void getFileName(){
    fstream finout("C:\\Users\\ltc\\Desktop\\data5\\FILENAME.TXT", ios::in | ios::out);
    ostringstream outstr;
    if (finout.is_open()){
        finout.seekg(0);
        int i = 0;
        while (finout.getline(data, 19)){
            outstr << data;

            names[i] = outstr.str();
            //cout <<setw(30)<<i<<setw(30)<<names[i]<<'\n';
            i++;
            outstr.str("");

        }
    }
    else
        cout << "failed" << endl;
}

最近事情较多,博客没有及时更新,但是留言私信我都会看到,欢迎交流!
青雲-吾道乐途

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

灰度共生矩阵的原理及实现(特征提取)-OpenCV 的相关文章

  • opencv 2.3.* 读取不工作

    我无法让 imread 工作 与这个人有同样的问题 OpenCV imwrite 2 2 在 Windows 7 上导致异常 并显示消息 OpenCV 错误 未指定错误 无法找到指定扩展名的编写器 https stackoverflow c
  • 指纹奇异点检测

    我正在尝试确定指纹的核心点和增量点 我正在使用庞加莱指数方法 但我无法成功检测到这一点 而且我不明白为什么 First I divide the image in 15x15 blocks then I calculate the x an
  • OpenCV Visual Studio ntdll.dll

    我尝试在 Visual Studio 2013 上使用 OpenCV 2 4 10 创建一个项目 但由于以下异常 到目前为止我运气不佳 请建议帮助 TIA letstryitonemoretime exe Win32 Loaded C Us
  • 仅获取图像中的外部轮廓

    我有这段代码 可以在图像中绘制轮廓 但我只需要外部轮廓 import cv2 import numpy as np camino C Users Usuario Documents Deteccion de Objetos 123 jpg
  • 如何去除给定图像中的噪声,使 ocr 输出完美?

    我已经对这个孟加拉文本图像进行了大津阈值处理 并使用 tesseract 进行 OCR 但输出非常糟糕 我应该应用什么预处理来消除噪音 我也想校正图像 因为它有轻微的倾斜 我的代码如下 import tesserocr from PIL i
  • OpenCV IP 相机应用程序崩溃 [h264 @ 0xxxxx] 访问单元中缺少图片

    我在 cpp 中有一个 opencv 应用程序 它使用 opencv 的简单结构捕获视频流并将其保存到视频文件中 它与我的网络摄像头完美配合 但是 当我运行它从 IP 摄像机捕获流时 它可能会在大约十秒后崩溃 我的编译命令是 g O3 IP
  • 使用 OpenCV 改进特征点匹配

    我想匹配立体图像中的特征点 我已经用不同的算法找到并提取了特征点 现在我需要一个良好的匹配 在本例中 我使用 FAST 算法进行检测和提取 BruteForceMatcher用于匹配特征点 匹配代码 vector lt vector
  • 如何确定与视频中物体的距离?

    我有一个从行驶中的车辆前面录制的视频文件 我将使用 OpenCV 进行对象检测和识别 但我停留在一方面 如何确定距已识别物体的距离 我可以知道我当前的速度和现实世界的 GPS 位置 但仅此而已 我无法对我正在跟踪的对象做出任何假设 我计划用
  • 在 Python 中将 OpenCV 帧流式传输为 HTML

    我正在尝试从 opencv Pyt hon 中的 URL 读取视频 然后逐帧处理它 然后将其发送到 HTML 页面 But I am only getting the first frame after that the program g
  • cv2.drawContours() - 取消填充字符内的圆圈(Python,OpenCV)

    根据 Silencer的建议 我使用了他发布的代码here https stackoverflow com questions 48244328 copy shape to blank canvas opencv python 482465
  • 在 Visual Studio 2012 中安装 OpenCV

    我正在尝试安装 OpenCV 来与 Visual Studio 一起使用 我使用的是2012Pro版本 但我认为它应该与vs10相同 我正在关注这个教程 http docs opencv org doc tutorials introduc
  • OpenCV:如何从网络摄像头获取原始 YUY2 图像?

    你知道如何获得吗raw YUY2来自网络摄像头的图像 使用 OpenCV DirectShow 无 VFW http opencv willowgarage com wiki CameraCapture http opencv willow
  • VideoCapture.read() 返回过去的图像

    我在跑python3 6 with openCV on the Raspberry pi OS is Raspbian 代码的大致结构如下 The image以时间间隔 3 5 分钟 捕获 被捕获image在函数中处理并返回度量 精度的种类
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • 深度估计的准确性 - 立体视觉

    我正在研究立体视觉 我对这个问题的深度估计的准确性感兴趣 这取决于几个因素 例如 适当的立体校准 旋转 平移和失真提取 图像分辨率 相机和镜头质量 失真越小 色彩捕捉正确 两个图像之间的匹配特征 假设我们没有低成本的相机和镜头 没有廉价的网
  • Opencv 2.4.2 代码讲解-人脸识别

    我参考OpenCV提供的文档制作了一个人脸识别程序 可以识别多个人脸 并且工作正常 在文档中 他们制作了省略号来突出显示脸部 我不明白的是他们如何计算椭圆的中心 他们的计算如下 for int i 0 i lt faces size i P
  • 使用 OpenCV 进行相机校准 - 如何调整棋盘方块大小?

    我正在使用 OpenCV Python 示例开发相机校准程序 来自 OpenCV 教程 http opencv python tutroals readthedocs io en latest py tutorials py calib3d
  • 选择合适的IDE

    您会推荐使用以下哪种 IDE 语言来在 Windows 下开发涉及识别手势并与操作系统交互的项目 我将使用 OpenCV 库来执行图像处理任务 之后 我将使用 win32 API 或 NET 框架与操作系统交互 具体取决于您建议的工具 性能
  • 未加载库:@rpath/libopenblasp-r0.2.19.dylib

    我应该如何解决这个问题 Monas MacBook Pro 02 02 mona python Python 3 6 1 Anaconda custom x86 64 default May 11 2017 13 04 09 GCC 4 2
  • 提取二值图像中的最中心区域

    我正在处理二进制图像 之前使用此代码来查找二进制图像中的最大区域 Use the hue value to convert to binary thresh 20 thresh thresh img cv2 threshold h thre

随机推荐

  • 【indemind双目惯性相机调试】sudo后找不到命令问题,环境变量问题

    问题1 报错 kanhao100 ubuntu x86 roslaunch imsee ros wrapper start launch RLException start launch is neither a launch file i
  • 深度学习_调参经验

    面对一个图像分类问题 可以有以下步骤 1 建立一个简单的CNN模型 一方面能够快速地run一个模型 以了解这个任务的难度 卷积层1 卷积核大小3 3 卷积核移动步长1 卷积核个数64 池化大小2 2 池化步长2 池化类型为最大池化 激活函数
  • leetCode热题46-51 解题代码,调试代码和思路

    前言 本文属于特定的六道题目题解和调试代码 正所谓磨刀不误砍柴功 下面我做这几篇文档对于涉及的题型或者数据结构的分析都很有帮助 贴出来仅供参考 1 69 x 的平方根 Easy 2022 12 28 101 2 22 括号生成 Medium
  • JSP核心标签库

    1 一般标签 在JSTL中 一般标签主要用在输出 设置变量值和错误处理等 这些是JSTL中使用最多的标签 1 计算一个表达式的值 然后把计算的结果输出到当前的JspWriter对象 调用的结果和Servlet中out println 语句效
  • linux 删除指定文件夹包含指定字符串的文件会把所有子文件夹包含的都删除

    需求就是在linux服务器上面删除 指定文件夹里面所有包含 delete 内容的文件 并且所有此文件夹里面的子文件夹查出来也要删除掉 使用以下脚本可以进行实现 grep r l delete data xargs rm rf 脚本说明 gr
  • 机器学习-fp16相乘

    1位符号位 5位指数位 10位尾数位 共16位 内存占2个字节 具体fp16表示法可以参照 机器学习 fp16表示 运算步骤 检查操作数中是否有0 Inf NaN NaN a Nan Inf 0 Nan Inf 0 Nan Inf a In
  • UTSim:无人机空中交通集成、控制和通信的框架和模拟器

    计算机仿真资源的可用性有利于无人机的开发和在现实应用中的集成 因为它们降低了成本 风险 开发和测试时间 并提高了安全水平 一些研究人员为自己的定制特殊无人机和应用开发了自己的模拟环境 然而 使用多个无人机仿真环境很难建立可持续的研究 因为很
  • CSAPP第三版运行时打桩Segmentation fault

    CSAPP第三版7 13 3节提到了运行时打桩机制 它可以在运行时将程序中对共享库函数的调用进行截获 替换为执行自己的代码 这个机制基于动态链接器的LD PRELOAD环境变量 如果LD PRELOAD环境变量被设置为一个共享路径名的列表
  • docker搭建registry私有仓库(centos7)

    搭建环境 master节点 registry端 192 168 1 10 node节点 客户端 192 168 1 20 关闭防火墙和selinux master和node节点都要关闭 root master systemctl stop
  • 【夜莺监控方案】04-k8s集群监控(下)(kube-state-metrics+cadvisor+prometheus+n9e及FAQ)

    文章目录 前言 4 接入prometheus 5 接入n9e 5 1 手动接入 方法一 5 2 导入模板 方法二 6 FAQ 6 1 集群数据时常取不到 现象 解决 前言 相关文档如下 03 k8s集群监控 上 4 接入prometheus
  • 【Navicat11安装教程】

    1 下载安装包 网盘地址 链接 提取码 bbqp 下载之后会得到这样的一个文件夹 2 安装 点击navicat111 mysql cs x64 exe安装软件 安装完成后 将PatchNavicat exe文件复制到安装路径下 如图 操作完
  • idea 工程目录横向变纵向【亲测可用】

    idea 目录横向变纵向往上搜好多都没啥用 下面亲测可用三步走 1 删除项目文件夹下的 idea文件夹 横向时点击 project 然后在 idea 下右击 Delete 就好了 2 关闭IDEA 3 重新用IDEA工具打开项目 然后就 O
  • Android如何配置init.rc中的开机启动进程(service)

    开篇 为什么写这篇文章 先说下我自己的情况 我是个普通的学生 之前在学校一直做Android应用开发 找实习的时候也一直想找相关的工作 来到现在这家公司以后 由于业务调整 被领导安排去做底层开发 本来我对底层的东西一无所知 加上其实并不感兴
  • Python 函数是传值还是传引用

    传递参数的时候 python不允许程序员选择采用传值还是传引用 Python参数传递采用的肯定是 传对象引用 的方式 实际上 这种方式相当于传值和传引用的一种综合 如果函数收到的是一个可变对象 比如字典或者列表 的引用 就能修改对象的原始值
  • C++中char和int型变量的一点心得

    字符字面值一般是用一对单引号来表示 char类型一般就是用字符字面值来初始化 赋值 由于char类型的是单字节长度 当给char类型的变量用字符 字面值赋值时 当单引号里面的内容超过一个字节时 系统会自动截取一个字节的内容给char变量 忽
  • JVM-了解概念

    1 什么是JVM JVM是 java Virtual Machine java虚拟机 的缩写 JVM是作用于计算设备的规范 它是一个虚构出来的计算机 是通过在实际计算机上仿真模拟各种计算机功能来实现的 java虚拟机包括一套字节码指令集 一
  • 苏宁 11.11:仓库内多 AGV 协作的全局路径规划算法研究

    本文为 InfoQ x 苏宁 2018双十一 技术特别策划系列文章之一 1 背景 随着物联网和人工智能的发展 越来越多的任务渐渐的被机器人取代 机器人逐渐在发展中慢慢进入物流领域 智能叉车 AGV Automated Guided Vehi
  • ROS :发送一个目标位置,机器人自动规划路线,移动到该位置。

    使用 Action move base msgs MoveBaseAction move base在world中的目标 新建send goal cpp send goal cpp Created on Aug 10 2016 Author
  • minio 配置

    文章目录 资源访问 用户和权限 策略 用户 Service Accounts java 连接 minio k8s 部署 minio 资源访问 某些资源例如图片 需要可以直接访问 新建桶 上传一张图片上去 点击桶设置 设置 Access Po
  • 灰度共生矩阵的原理及实现(特征提取)-OpenCV

    最近在研究机器学习相关内容 后面会尽量花时间整理成一个系列的博客 然后朋友让我帮他实现一种基于SVR支持向量回归的图像质量评价方法 然而在文章的开头竟然发现 灰度共生矩阵这个陌生的家伙 于是便有此文 主要参考博客1 http blog cs