【Gabor】基于多尺度多方向Gabor融合+分块直方图的表情识别

Topic:表情识别
Env: win10 + Pycharm2018 + Python3.6.8
Date:   2019/6/23~25 by hw_Chen2018                                  CSDN: https://blog.csdn.net/qq_34198088/article/details/97895876

【感谢参考文献作者的辛苦付出;编写不易,转载请注明出处,感谢!】
一.简要介绍
  本文方法参考文献【1】的表情识别方法,实验数据集为JAFFE,实验方法较为传统:手工设计特征+浅层分类器,选择常规的划分训练集与测试方法:70%训练集、30%测试集。最后识别正确率73%,比不上目前深度学习方法,想要学习深度学习的朋友,抱歉本文不能提供任何帮助,不过做为Gabor滤波器的学习,可以作为参考。
二.数据集
  实验中采用Jaffe数据库,数据库中包含了213幅(每幅图像的分辨率:256像素×256像素)日本女性的脸相,每幅图像都有原始的表情定义。表情库中共有10个人,每个人有7种表情(中性脸、高兴、悲伤、惊奇、愤怒、厌恶、恐惧)。JAFFE数据库均为正面脸相,且把原始图像进行重新调整和修剪,使得眼睛在数据库图像中的位置大致相同,脸部尺寸基本一致,光照均为正面光源,但光照强度有差异。【2】
三.Gabor滤波器
  Gabor小波与人类视觉系统中简单细胞的视觉刺激响应非常相似。Gabor小波对于图像的边缘敏感,能够提供良好的方向选择和尺度选择特性,而且对于光照变化不敏感,能够提供对光照变化良好的适应性。因此Gabor小波被广泛应用于视觉信息理解。
在空域,一个2维的Gabor滤波器是一个正弦平面波和高斯核函数的乘积。【2】
                                

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述



Gabor滤波器的表达式如下:
                                                                                                    

在这里插入图片描述


  每个参数的意义以及对比图,可参考【3】
三.实验过程
1.数据库中灰度图分辨率是256256,实验中所用到的是进过裁剪的人脸图像,大小为48*48。  

                                                               

在这里插入图片描述


2.构建多尺度、多方向Gabor滤波器,实验中构建的滤波器尺度为5,方向数为8,下图就是所构建的Gabor滤波。值得注意的是通过Gabor滤波得到的结果是一个复数,在实验中只选用了实部进行实验,后面展示的一些结果图都是结果的实部。

                                                              

在这里插入图片描述


3.人脸多尺度多方向特征

在这里插入图片描述


4.我们前面得到了5个尺度,8个方向的Gabor特征图,融合规则是对每个尺度进行操作,融合的第一步是,在同一尺度下,每个方向的特征图中,逐像素与0比较,大于0的置1,小于等于0置0,之后对每个像素进行二进制编码,在右边公式中,u代表方向序号,v代表尺度,对于融合后的图像的每个像素,它等于每个方向的的二进制编码之和。更多融合方法可查阅文献【1】。

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


5.分块直方图
  前面滤波器也提到,Gabor滤波器具有很好的局部特性和方向特性,而图像直方图从图像整体分布角度考虑,反映了图像的统计特性,但是却丢失了图像结构特性,因此【1】中避免使用全局图像直方图,采用分块直方图的方法,即保持了Gabor的局部细节,又保持了一定的结构特性。本文划分成36个小块。

在这里插入图片描述


在这里插入图片描述


6.降维与分类器训练
由于经过分块直方图后特征维数46080,相对于共213个样本的JAFFE数据集来说,维数偏高,同时也存在特征冗余,即并不是所有特征都对分类起积极作用,这里使用比较简单的PCA进行降维和特征选择,感兴趣的朋友可以搜下其他的特征选择,比如常用的包裹式、过滤式等等的特征选择方法以及以流形学习为代表的非线性降维方法等等。选择前13个主成分,贡献率达到90%。使用随机森林进行分类。

在这里插入图片描述


四.实验结果与分析


                                                        ROC曲线                                                                                            PR曲线                                                                   

在这里插入图片描述

       

在这里插入图片描述

         

混淆矩阵

在这里插入图片描述


(1)对于实验中使用的特征提取及构建的分类器,通过ROC曲线可知,各类别中分类准确率最高的是第一类,对于测试集全部分类正确,其AUC等于1;分类正确率最低是第三类,低于平均正确率,其AUC等于0.83。
(2) 对于实验中使用的特征提取及构建的分类器,通过PR曲线可知,各类别中分类准确率最高的仍然是第一类,对于测试集全部分类正确,PR曲线面积等于1;分类正确率最低仍然是第三类,同样低于平均正确率,PR曲线面积等于0.584。
(3)通过混线矩阵可以很直观看出,分类器容易把第二类分成第一类,分类结果最好的仍然是第一类。

五.实验代码
1.提取特征并保存在CSV文件中。(部分代码参考了OpenCV中Gabor滤波器)

# coding:utf-8
# ------------------------------------
# topic: discrete express recognition
# method: Gabor Multi-orientation Features Fusion and Block Histogram  +  random forest
# source: 刘帅师等: 基于 Gabor 多方向特征融合与分块直方图的人脸表情识别方法 等
# env: win10 + pycharm + Python3.6.8
# date: 2019/6/21~25
# author: Chen_hw
# CSDN:https://blog.csdn.net/qq_34198088
# 编写不易,转载请注明出处!
# ------------------------------------
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
from scipy import signal
import matplotlib
import time
import csv
matplotlib.rcParams[font.sans-serif] = [SimHei]
matplotlib.rcParams[font.family] = sans-serif
matplotlib.rcParams[axes.unicode_minus] = False

class DiscreteAffectModel(object):
    def __init__(self,dataset_path):
        self.emotion ={0:Angry,1:Disgust,2:Fear,3:Happy,4:Sad,5:Surprise,6:Neutral}
        self.path = dataset_path
        self.gabor_filter_size = [50,50]
        self.gabor_filter_lambda = [2*np.power(2,0.5),3*np.power(2,4*np.power(2,5*np.power(2,6*np.power(2,0.5)]                 # 正弦因子波长。通常大于等于2.但不能大于输入图像尺寸的五分之一
        self.gabor_filter_sigma = [1.58,2.38,3.17,3.96,4.75]                                # 高斯包络的标准差.带宽设置为1时,σ 约= 0.56 λ
        self.gabor_filter_theta = [theta for theta in np.arange(0,np.pi,np.pi / 8) ]  # Gabor函数平行条纹的法线方向
        self.gabor_filter_gamma = 0.5                                   # 空间纵横比
        self.gabor_filter_psi = 0                                       # 相移
        self.filters_real = []                                          # 滤波器实数部分
        self.filters_imaginary = []                                     # 滤波器虚数部分
        self.filtering_result_real_component = []
        self.load_dataset()
        self.build_gabor_filter()
        # self.show_gabor_filters()
        # self.show_different_gabor_filteringResult()
        # self.show_fusion_rule_1_result()
        self.process_images()


        # a = np.array([[1,2,3,4,5,6,7,8],
        #               [1,8]])
        # b = self.block_histogram(a)
        # print(b)


    def load_dataset(self):
        dataset = pd.read_csv(self.path,dtype=a)
        self.label = np.array(dataset[emotion])
        self.img_data = np.array(dataset[pixels])

    def build_gabor_filter(self):
        ‘‘‘构建滤波器,分为实部和虚部‘‘‘
        for r in range(len(self.gabor_filter_lambda)):      # 尺度
            for c in range(len(self.gabor_filter_theta)):   # 方向
                self.filters_real.append(self.build_a_gabor_filters_real_component(self.gabor_filter_size,self.gabor_filter_sigma[r],self.gabor_filter_theta[c],self.gabor_filter_lambda[r],self.gabor_filter_gamma,self.gabor_filter_psi))
        for r in range(len(self.gabor_filter_lambda)):
            for c in range(len(self.gabor_filter_theta)):
                self.filters_imaginary.append(self.build_a_gabor_filters_imaginary_component(self.gabor_filter_size,self.gabor_filter_psi))

    def show_fusion_rule_1_result(self):
        ‘‘‘显示规则1的融合结果‘‘‘
        img = np.fromstring(self.img_data[0],dtype=float,sep= )
        img = img.reshape((48,48))
        # 实部
        filter_result_real_component = []                               # 滤波结果实部
        for i in range(len(self.filters_real)):
            cov_result = signal.convolve2d(img,self.filters_real[i],mode=same,boundary=fill,fillvalue=0)
            filter_result_real_component.append(cov_result)
        dst = self.fusion_rule_1(filter_result_real_component)
        plt.figure()
        plt.suptitle("融合结果__实部")
        for j in range(5):
            plt.subplot(1,j+1)
            plt.imshow(dst[j],cmap="gray")
        plt.show()

        filter_result_imaginary_component = []                               # 滤波结果实部
        for i in range(len(self.filters_imaginary)):
            cov_result = signal.convolve2d(img,self.filters_imaginary[i],fillvalue=0)
            filter_result_imaginary_component.append(cov_result)
        dst = self.fusion_rule_1(filter_result_imaginary_component)
        plt.figure()
        plt.suptitle("融合结果__虚部")
        for j in range(5):
            # plt.title(‘融合后‘)
            plt.subplot(1,cmap="gray")
        plt.show()
        plt.show()

    def show_gabor_filters(self):
        ‘‘‘ 显示Gabor滤波器,分为实部和虚部 ‘‘‘
        # 实部
        plt.figure(1,figsize=(9,9))
        plt.tight_layout()
        plt.axis("off")
        plt.suptitle("实部")
        for i in range(len(self.filters_real)):
            plt.subplot(5,8,i + 1)
            plt.imshow(self.filters_real[i],cmap="gray")

        plt.show()
        # 虚部
        plt.figure(2,9))
        plt.suptitle("虚部")
        for i in range(len(self.filters_imaginary)):
            plt.subplot(5,i + 1)
            plt.imshow(self.filters_imaginary[i],cmap="gray")
        plt.show()

    def show_different_gabor_filteringResult(self):
        ‘‘‘展示不同滤波器对于同一副图像的滤波结果,分为实部与虚部‘‘‘
        img = np.fromstring(self.img_data[0],48))
        # 实部
        plt.figure(3,9))
        plt.suptitle(real component)
        for i in range(len(self.filters_real)):
            cov_result =signal.convolve2d(img,fillvalue=0)
            # cov_result = np.imag(cov_result)
            # cov_result = cv2.filter2D(img,cv2.CV_8UC1,self.filters[i])
            # cov_result = np.imag(cov_result)
            plt.subplot(5,i+1)
            plt.imshow(cov_result,cmap="gray")
        plt.show()
        # 虚部
        plt.figure(4,9))
        plt.suptitle(imaginary component)
        for i in range(len(self.filters_imaginary)):
            cov_result =signal.convolve2d(img,cmap="gray")
        plt.show()

    def build_a_gabor_filters_real_component(self,ksize,# 滤波器尺寸; type:list
                                            sigma,# 高斯包络的标准差
                                            theta,# Gaobr函数平行余纹的法线方向
                                            lambd,# 正弦因子的波长
                                            gamma,# 空间纵横比
                                            psi):                      # 相移
        ‘‘‘ 构建一个gabor滤波器实部‘‘‘
        g_f = []
        x_max = int(0.5*ksize[1])
        y_max = int(0.5*ksize[0])
        sigma_x = sigma
        sigma_y = sigma / gamma
        c = np.cos(theta)
        s = np.sin(theta)
        scale = 1
        cscale = np.pi*2/lambd
        ex = -0.5 / (sigma_x * sigma_x)
        ey = -0.5 / (sigma_y * sigma_y)
        for y in range(-y_max,y_max,1):
            temp_line = []
            for x in range(-x_max,x_max,1):
                xr = x * c + y * s
                yr = -x * s + y * c
                temp = scale * np.exp(ex * xr * xr + ey * yr * yr) * np.cos(cscale * xr + psi)
                temp_line.append(temp)
            g_f.append(np.array(temp_line))
        g_f = np.array(g_f)
        return g_f

    def build_a_gabor_filters_imaginary_component(self,# 滤波器尺寸; type:list
                                                sigma,# 高斯包络的标准差
                                                theta,# Gaobr函数平行余纹的法线方向
                                                lambd,# 正弦因子的波长
                                                gamma,# 空间纵横比
                                                psi):
        ‘‘‘ 构建一个gabor滤波器虚部‘‘‘
        g_f = []
        x_max = int(0.5*ksize[1])
        y_max = int(0.5*ksize[0])
        sigma_x = sigma
        sigma_y = sigma / gamma
        c = np.cos(theta)
        s = np.sin(theta)
        scale = 1
        cscale = np.pi*2/lambd
        ex = -0.5 / (sigma_x * sigma_x)
        ey = -0.5 / (sigma_y * sigma_y)
        for y in range(-y_max,1):
                xr = x * c + y * s
                yr = -x * s + y * c
                temp = scale * np.exp(ex * xr * xr + ey * yr * yr) * np.sin(cscale * xr + psi)
                temp_line.append(temp)
            g_f.append(np.array(temp_line))
        g_f = np.array(g_f)
        return g_f

    def fusion_rule_1(self,filteringResult):
        ‘‘‘ 融合规则1:详见论文【刘帅师等: 基于 Gabor 多方向特征融合与分块直方图的人脸表情识别方法】
            融合同一尺度下不同方向的图像
            filteringResult: 每个尺度下各方向的滤波结果,实部与虚部计算都可调用。输入类型为列表,列表中每个元素类型为array
            return:融合后的array
        ‘‘‘
        comparedFilteringResult = []                                   # 存储与0比较后的列表
        fusion_result = []                                             # 5个尺度下,每个尺度下个方向融合后结果,类型为list大小为5,每个元素为array
        for content in filteringResult:
            temp = list(content.flatten())
            temp = [1 if i > 0 else 0 for i in temp]
            comparedFilteringResult.append(temp)
        # print(len(comparedFilteringResult[0]))
        for count in range(5):      # 5个尺度
            count *= 8
            temp = []
            for ele in range(len(comparedFilteringResult[0])):             # 8个方向
                tmp = comparedFilteringResult[count + 0][ele] * np.power(2,0) +                      comparedFilteringResult[count + 1][ele] * np.power(2,1) +                      comparedFilteringResult[count + 2][ele] * np.power(2,2) +                       comparedFilteringResult[count + 3][ele] * np.power(2,3) +                      comparedFilteringResult[count + 4][ele] * np.power(2,4) +                       comparedFilteringResult[count + 5][ele] * np.power(2,5) +                       comparedFilteringResult[count + 6][ele] * np.power(2,6) +                       comparedFilteringResult[count + 7][ele] * np.power(2,7)
                temp.append(tmp)
            # print(len(temp))
            fusion_result.append(temp)
        fusion_result = [np.array(i) for i in fusion_result]
        fusion_result = [arr.reshape((48,48)) for arr in fusion_result]
        return fusion_result

    def get_fusionRule1_result_realComponent(self):
        ‘‘‘提取每幅图像多尺度多方向Gabor特征,融合每个尺度下各方向滤波结果,将融合图像保存在csv中‘‘‘
        # multiscale_multiangle_gabor_feature_InOneImage = []   # 单幅图像多尺度多方向Gabor特征
        gabor_feature_images_real_component = []                              # 全部图像的Gabor特征实部
        dst_real_component = []     # 保存融合图像
        # 提取特征
        for sample in range(self.img_data.shape[0]):                         # self.img_data.shape[0]
            img = np.fromstring(self.img_data[sample],sep= )
            img = img.reshape((48,48))
            tempRealComponent = []
            for filter in self.filters_real:
                tempCovResult = signal.convolve2d(img,filter,fillvalue=0)
                tempRealComponent.append(tempCovResult)
            gabor_feature_images_real_component.append(tempRealComponent)  # 其中每个元素为5个尺度、8个方向,共40幅图像的列表

        for multi_info in gabor_feature_images_real_component:
            temp = self.fusion_rule_1(multi_info)
            dst_real_component.append(temp)

        return dst_real_component           # 显示某一图像(如0)下某一尺度(如尺度序号0)的融合图像方法:dst_real_component[0][0]

    def get_block_histogram(self,fused_image_list):
        ‘‘‘
        分块直方图
        :param fused_image_list: 含融合图像的列表,样本数为213,大小为213,其中每个元素类型列表,5个尺度的融合图像,大小为5,
        输入的元素的元素类型为array,包含48*48的array5个
        :return: 每幅图像的直方图特征,共213条样本,每个样本特征维度5*6*6*256=46080
        ‘‘‘
        block_histogram_feature = []                # 不同图像直方图特征,每一幅图像(5个尺度的融合图像)的直方图特征为其中一个元素
        for multi_sclae_image in fused_image_list:  # 遍历每幅图像
            temp = []
            for image in multi_sclae_image:         # 遍历每幅图像下各尺度融合图像
                tmp_block_histogram_feature = self.block_histogram(image)
                temp.append(tmp_block_histogram_feature)
            temp = np.array(temp)
            temp = temp.flatten()
            block_histogram_feature.append(temp)
            # print(f"特征长度:{temp.shape}")
        block_histogram_feature = np.array(block_histogram_feature)
        # block_histogram_feature = block_histogram_feature.flatten()   # 展开成一维
        return block_histogram_feature

    def process_images(self):
        ‘‘‘
        提取每幅图像特征,并保存在csv中
        :return:
        ‘‘‘
        fusionRule1_result_real = self.get_fusionRule1_result_realComponent()
        block_histgram_feature = self.get_block_histogram(fusionRule1_result_real)
        # print(f"类型:{type(block_histgram_feature)}")
        # print(block_histgram_feature.shape)

        with open("gabor_feature_real_component.csv",w) as gf:
            writer = csv.writer(gf)
            writer.writerow([label,feature])
            for i in range(block_histgram_feature.shape[0]):
                data_list = list(block_histgram_feature[i,:])
                b =  .join(str(x) for x in data_list)
                l = np.hstack([self.label[i],b   ])
                writer.writerow(l)

    def block_histogram(self,inputImage):
        ‘‘‘
        计算分块直方图特征,块大小8*8
        :param inputImage: 输入灰度图,类型ndarray,大小48*48
        :return: 分块直方图特征,类型为ndarray,一维
        ‘‘‘
        block_histogram_feature = []
        for row in range(int(inputImage.shape[0]/8)):
            for col in range(int(inputImage.shape[1]/8)):
                # hist = cv2.calcHist([inputImage[row*8:row*8+8,col*8:col*8+8]],[0],None,[256],[0,255])
                hist,_ = np.histogram(inputImage[row*8:row*8+8,col*8:col*8+8],bins=[i for i in range(257)])
                hist = np.array(hist)
                block_histogram_feature.append(hist)
        block_histogram_feature = np.array(block_histogram_feature)
        block_histogram_feature = block_histogram_feature.flatten()
        return block_histogram_feature

if __name__ ==__main__:
    time_start = time.time()
    classify_test = DiscreteAffectModel(face.csv)
    time_end = time.time()
    print(f"耗时:{time_end - time_start}"

2. 分类器训练与测试

 

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.ensemble import GradientBoostingClassifier
from sklearn import metrics
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import learning_curve
from sklearn.model_selection import cross_val_predict
import matplotlib.pyplot as plt
import scikitplot as skplt

class classify(object):
    def __init__(self):
        self.load_dataset()
        self.classify_RF()
        # self.classify_GBDT()

    def load_dataset(self):
        data = pd.read_csv(rgabor_feature_real_component.csv,dtype=a)
        self.label = np.array(data[label])
        self.label = list(self.label)
        self.label = np.array([int(x) for x in self.label])

        self.feature = []
        feature = np.array(data[feature])
        for i in range(feature.shape[0]):
            temp = np.fromstring(feature[i],sep= )
            self.feature.append(temp)
        self.feature = np.array(self.feature)

        # 降维
        pca = PCA(210)
        self.feature = pca.fit_transform(self.feature)
        # print(sum(pca.explained_variance_ratio_[:210]))
        # print(self.feature)

    def classify_RF(self):
        self.train_feature,self.test_feature,self.train_label,self.test_label =             train_test_split(self.feature,self.label,test_size=0.3,random_state=0)
        rfc = RandomForestClassifier(n_estimators=900,criterion=gini,max_depth=10,min_samples_split=2,min_samples_leaf=1,oob_score=False,n_jobs=-1,random_state=0)
        rfc.fit(self.train_feature,self.train_label)
        print(rfc.predict(self.test_feature))
        print(self.test_label)
        score = rfc.score(self.test_feature,self.test_label)
        print(f"score:{score}")
        # print(len(rfc.feature_importances_))

        predict_proba = rfc.predict_proba(self.test_feature)
        skplt.metrics.plot_roc(self.test_label,predict_proba)
        plt.show()

        skplt.metrics.plot_precision_recall_curve(self.test_label,predict_proba,cmap="nipy_spectral")
        plt.show()

        predictions = cross_val_predict(rfc,self.train_feature,self.train_label)
        plot = skplt.metrics.plot_confusion_matrix(self.train_label,predictions,normalize=True)
        plt.show()

    def classify_GBDT(self):
        self.train_feature,random_state=0)
        # gbdtc = GradientBoostingClassifier(n_estimators=2000,
        #                                    max_depth=5,
        #                                    min_samples_split=2,
        #                                    learning_rate=0.01)
        # gbdtc.fit(self.train_feature,self.train_label)
        # y_predicted = gbdtc.predict(self.test_feature)
        # print(f"准确率:{metrics.accuracy_score(self.test_label,y_predicted)}")

        param_test1 = [{n_estimators:[i for i in range(900,3050,50)]}]
        gsearch1 = GridSearchCV(estimator = GradientBoostingClassifier(learning_rate=0.1,min_samples_split=300,min_samples_leaf=20,max_depth=8,max_features=sqrt,subsample=0.8,random_state=10),param_grid = param_test1,scoring=roc_auc,iid=False,cv=5)
        # gsearch1.fit(self.train_feature,self.train_label)
        
if __name__ == "__main__":
    c_test = classify()

 

【1】刘帅师,田彦涛,万川.基于Gabor多方向特征融合与分块直方图的人脸表情识别方法[J].自动化学报,2011,37(12):1455-1463.

【2】https://blog.csdn.net/zdyueguanyun/article/details/8525739

【3】https://www.cnblogs.com/arxive/p/4990754.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用OpenCV实现视频去抖 整体步骤: 设置输入输出视频 寻找帧之间的移动:使用opencv的特征检测器,检测前一帧的特征,并使用Lucas-Kanade光流算法在下一帧跟踪这些特征,根据两组点,将前一个坐标系映射到当前坐标系完成刚性(欧几里得)变换,最后使用数组纪录帧之间的运动。 计算帧之间的平
前言 对中文标题使用余弦相似度算法和编辑距离相似度分析进行相似度分析。 准备数据集part1 本次使用的数据集来源于前几年的硕士学位论文,可根据实际需要更换。结构如下所示: 学位论文题名 基于卷积神经网络的人脸识别研究 P2P流媒体视频点播系统设计和研究 校园网安全体系的设计与实现 无线传感器网络中
前言 之前尝试写过一个爬虫,那时对网页请求还不够熟练,用的原理是:爬取整个html文件,然后根据标签页筛选有效信息。 现在看来这种方式无疑是吃力不讨好,因此现在重新写了一个爬取天气的程序。 准备工作 网上能轻松找到的是 101010100 北京这种编号,而查看中国气象局URL,他们使用的是北京545
前言 本文使用Python实现了PCA算法,并使用ORL人脸数据集进行了测试并输出特征脸,简单实现了人脸识别的功能。 1. 准备 ORL人脸数据集共包含40个不同人的400张图像,是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建。此数据集包含40个类,每个类含10张图
前言 使用opencv对图像进行操作,要求:(1)定位银行票据的四条边,然后旋正。(2)根据版面分析,分割出小写金额区域。 图像校正 首先是对图像的校正 读取图片 对图片二值化 进行边缘检测 对边缘的进行霍夫曼变换 将变换结果从极坐标空间投影到笛卡尔坐标得到倾斜角 根据倾斜角对主体校正 import
天气预报API 功能 从中国天气网抓取数据返回1-7天的天气数据,包括: 日期 天气 温度 风力 风向 def get_weather(city): 入参: 城市名,type为字符串,如西安、北京,因为数据引用中国气象网,因此只支持中国城市 返回: 1、列表,包括1-7的天气数据,每一天的分别为一个
数据来源:House Prices - Advanced Regression Techniques 参考文献: Comprehensive data exploration with Python 1. 导入数据 import pandas as pd import warnings warnin
同步和异步 同步和异步是指程序的执行方式。在同步执行中,程序会按顺序一个接一个地执行任务,直到当前任务完成。而在异步执行中,程序会在等待当前任务完成的同时,执行其他任务。 同步执行意味着程序会阻塞,等待任务完成,而异步执行则意味着程序不会阻塞,可以同时执行多个任务。 同步和异步的选择取决于你的程序需
实现代码 import time import pydirectinput import keyboard if __name__ == '__main__': revolve = False while True: time.sleep(0.1) if keyboard.is_pr
本文从多个角度分析了vi编辑器保存退出命令。我们介绍了保存和退出vi编辑器的命令,以及如何撤销更改、移动光标、查找和替换文本等实用命令。希望这些技巧能帮助你更好地使用vi编辑器。
Python中的回车和换行是计算机中文本处理中的两个重要概念,它们在代码编写中扮演着非常重要的角色。本文从多个角度分析了Python中的回车和换行,包括回车和换行的概念、使用方法、使用场景和注意事项。通过本文的介绍,读者可以更好地理解和掌握Python中的回车和换行,从而编写出更加高效和规范的Python代码。
SQL Server启动不了错误1067是一种比较常见的故障,主要原因是数据库服务启动失败、权限不足和数据库文件损坏等。要解决这个问题,我们需要检查服务日志、重启服务器、检查文件权限和恢复数据库文件等。在日常的数据库运维工作中,我们应该时刻关注数据库的运行状况,及时发现并解决问题,以确保数据库的正常运行。
信息模块是一种可重复使用的、可编程的、可扩展的、可维护的、可测试的、可重构的软件组件。信息模块的端接需要从接口设计、数据格式、消息传递、函数调用等方面进行考虑。信息模块的端接需要满足高内聚、低耦合的原则,以保证系统的可扩展性和可维护性。
本文从电脑配置、PyCharm版本、Java版本、配置文件以及程序冲突等多个角度分析了Win10启动不了PyCharm的可能原因,并提供了解决方法。
本文主要从多个角度分析了安装SQL Server 2012时可能出现的错误,并提供了解决方法。
Pycharm是一款非常优秀的Python集成开发环境,它可以让Python开发者更加高效地进行代码编写、调试和测试。在Pycharm中设置解释器非常简单,我们可以通过创建新项目、修改项目解释器、设置全局解释器等多种方式进行设置。
Python中有多种方法可以将字符串转换为整数,包括使用int()函数、try-except语句、正则表达式、map()函数、ord()函数和reduce()函数。在实际应用中,应根据具体情况选择最合适的方法。
本文介绍了导入CSV文件的多种方法,包括使用Excel、Python和R等工具。同时,还介绍了导入CSV文件时需要注意的一些细节和问题。CSV文件是数据处理和分析中不可或缺的一部分,希望本文能够对读者有所帮助。
mongodb是一种新型的数据库,它采用了面向文档的数据模型,具有灵活性、高性能和高可用性等优势。但是,mongodb也存在数据结构混乱、安全性和学习成本高等问题。
当Python运行不了时,我们应该从代码、Python环境、操作系统和硬件设备等多个角度来排查问题,并采取相应的解决措施。