前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >人脸识别系统设计实践:代码生成训练PNET的图片数据

人脸识别系统设计实践:代码生成训练PNET的图片数据

作者头像
望月从良
发布于 2021-01-04 03:16:07
发布于 2021-01-04 03:16:07
52000
代码可运行
举报
文章被收录于专栏:Coding迪斯尼Coding迪斯尼
运行总次数:0
代码可运行

上一节我们了解了PNET的基本原理,本节看看如何生成PNET需要的训练数据。总体而言我们需要产生两部分数据,一部分图片里面包含人脸,另一部分不包含人脸。这里的“包含”或“不包含”并不是指图片中完全没有人脸,而是图片中人脸占据的比率超过一定的阈值时就可以认为给定图片包含人脸。

算法会设定三个阈值,当人脸在图片区域占据比率不超过30%,那么认为图片不包含人脸。如果超过30%但是不到45%,那么图片属于“中性”,当人脸占据区域超过65%则断定图片内含有人脸。训练使用的数据集为WIDERFace,该数据集不但包含了大量含有人脸的图片,而且还通过文本文件详细描述了每张图片中人脸所在的坐标位置。

下载给定数据集后解压,可以看到路径下有多个文件夹和一个文本文件,文件夹中包含不同类型的人脸图片,文本文件描述了每张图片中人脸的坐标位置,例如打开文本可以看到如下一行信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
0_Parade_marchingband_1_205 59.60 56.00 78.29 74.94 39.41 1.66 56.60 22.60 90.26 18.61 106.71 41.04 144.10 15.87 161.05 37.30 117.68 30.32 132.38 47.02 201.93 16.36 221.37 36.06 162.79 53.26 176.50 72.45 97.98 53.26 113.19 79.43 9.34 85.48 22.43 106.57 59.35 116.15 76.15 139.59 45.29 161.07 59.74 182.17 18.25 247.82 48.34 278.95 114.79 237.10 139.12 265.09 210.80 239.19 231.73 266.66 308.43 259.50 332.99 285.24 402.90 205.89 433.36 242.02 260.95 141.52 280.40 164.15 283.12 151.71 301.22 170.71 353.49 159.85 370.91 183.38 238.07 37.05 250.12 56.08 251.39 28.39 271.26 47.62 266.40 56.71 280.56 75.95 357.28 80.38 371.45 101.73 489.01 112.72 508.57 135.54 545.43 122.50 561.98 148.07 511.58 73.61 529.88 94.92 543.67 75.11 560.97 100.18 544.68 49.29 561.22 67.59 562.48 67.09 583.04 96.17 464.94 68.59 482.75 94.92 502.80 37.00 520.86 56.81 595.57 53.05 612.62 70.85 574.01 138.29 588.80 159.86 554.71 164.62 567.99 185.18 497.47 256.35 526.72 284.60 580.56 239.07 607.82 267.32 706.86 166.62 747.08 209.82 654.28 140.01 672.72 164.13 533.31 3.35 549.04 20.67 596.23 20.99 613.08 39.74 684.31 47.47 699.18 67.20 665.16 40.90 678.88 58.91 659.73 6.03 673.73 27.46 747.49 10.31 765.78 32.90 795.22 17.75 809.80 37.76 813.52 16.03 830.67 41.19 850.39 39.76 870.40 62.63 806.94 59.48 823.81 84.06 739.20 54.34 756.92 78.35 831.81 117.80 852.40 140.38 866.69 108.36 882.70 132.09 798.11 221.94 830.85 260.00 870.04 236.21 898.59 267.28 911.23 223.52 927.69 245.54 991.32 142.56 1011.70 164.67 940.88 88.66 958.15 109.39 917.04 24.75 939.50 53.08 1000.30 25.44 1017.23 45.83 932.24 58.95 949.51 83.14 759.27 34.53 774.08 57.43 758.94 127.71 775.70 152.78 346.72 22.38 363.76 40.91 25.75 42.00 40.87 63.96 47.01 23.81 62.83 45.78 328.05 219.76 350.44 243.90 "

数据以空格将不同信息分离,第一个空格前面的字符串对应图片的名称,上面数据就表明有一张名为0_Parade_marchingband_1_205.jpg的图片,后面的数字以每四个为一组分别对应一张人脸在图片中的坐标,因此我们可以通过这些数据将图片中的人脸“框”出来:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
txt_line = "0_Parade_marchingband_1_205 59.60 56.00 78.29 74.94 39.41 1.66 56.60 22.60 90.26 18.61 106.71 41.04 144.10 15.87 161.05 37.30 117.68 30.32 132.38 47.02 201.93 16.36 221.37 36.06 162.79 53.26 176.50 72.45 97.98 53.26 113.19 79.43 9.34 85.48 22.43 106.57 59.35 116.15 76.15 139.59 45.29 161.07 59.74 182.17 18.25 247.82 48.34 278.95 114.79 237.10 139.12 265.09 210.80 239.19 231.73 266.66 308.43 259.50 332.99 285.24 402.90 205.89 433.36 242.02 260.95 141.52 280.40 164.15 283.12 151.71 301.22 170.71 353.49 159.85 370.91 183.38 238.07 37.05 250.12 56.08 251.39 28.39 271.26 47.62 266.40 56.71 280.56 75.95 357.28 80.38 371.45 101.73 489.01 112.72 508.57 135.54 545.43 122.50 561.98 148.07 511.58 73.61 529.88 94.92 543.67 75.11 560.97 100.18 544.68 49.29 561.22 67.59 562.48 67.09 583.04 96.17 464.94 68.59 482.75 94.92 502.80 37.00 520.86 56.81 595.57 53.05 612.62 70.85 574.01 138.29 588.80 159.86 554.71 164.62 567.99 185.18 497.47 256.35 526.72 284.60 580.56 239.07 607.82 267.32 706.86 166.62 747.08 209.82 654.28 140.01 672.72 164.13 533.31 3.35 549.04 20.67 596.23 20.99 613.08 39.74 684.31 47.47 699.18 67.20 665.16 40.90 678.88 58.91 659.73 6.03 673.73 27.46 747.49 10.31 765.78 32.90 795.22 17.75 809.80 37.76 813.52 16.03 830.67 41.19 850.39 39.76 870.40 62.63 806.94 59.48 823.81 84.06 739.20 54.34 756.92 78.35 831.81 117.80 852.40 140.38 866.69 108.36 882.70 132.09 798.11 221.94 830.85 260.00 870.04 236.21 898.59 267.28 911.23 223.52 927.69 245.54 991.32 142.56 1011.70 164.67 940.88 88.66 958.15 109.39 917.04 24.75 939.50 53.08 1000.30 25.44 1017.23 45.83 932.24 58.95 949.51 83.14 759.27 34.53 774.08 57.43 758.94 127.71 775.70 152.78 346.72 22.38 363.76 40.91 25.75 42.00 40.87 63.96 47.01 23.81 62.83 45.78 328.05 219.76 350.44 243.90 "
annotation = txt_line.strip().split(' ')
img_path = annotation[0]
box = list(map(float, annotation[1:]))
boxes = np.array(box, dtype=np.float32).reshape(-1, 4)
print("image contains {} faces".format(len(boxes)))
img = cv2.imread(img_path + ".jpg")
for box in boxes:
  top_left = (box[0], box[1])
  bottom_right = (box[2], box[3])
  img = cv2.rectangle(img, top_left, bottom_right, (255,0,0), 1)

cv2_imshow(img)

上面代码运行后结果如下:

可以看到图片中很多人脸都被蓝色方框选中,由此根据数据集给定信息我们可以构造不同类型的训练数据,第一种称为”neg”的图片,图片中人脸占总区域的比率不到0.3,第二种称为”part”,这种人脸在这种图片中占据的区域在0.3到0.4之间,第三种称为”pos”,人脸占据图片区域在0。65以上,为了更形象的展示这三种图片的特性,我们选择一张只有一个人脸的图片进行实例讲解,首先我们把读取人脸坐标的逻辑用一个函数封装起来,然后加载实例需要的人脸图片:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def  get_img_boxes(txt_line):
  cur_path = os.getcwd()
  annotation = txt_line.strip().split(' ')
  img_path = os.path.join(cur_path, annotation[0] + ".jpg")
  box = list(map(float, annotation[1:]))
  boxes = np.array(box, dtype=np.float32).reshape(-1, 4)
  return img_path, boxes

txt_line = "0_Parade_marchingband_1_849 448.51 329.63 570.09 478.23 "
img_path, boxes = get_img_boxes(txt_line)

print("image contains {} faces".format(len(boxes)))
face_img = cv2.imread(img_path)
for box in boxes:
     top_left = (box[0], box[1])
     bottom_right = (box[2], box[3])
     face_img = cv2.rectangle(face_img, top_left, bottom_right, (255,0,0), 1)
cv2_imshow(face_img)

上面代码运行后结果如下:

接下来我们要生成”neg”属性的训练图片,算法的基本思路是,在图片上随机选择一系列区域,然后计算所选择区域与人脸区域的“并”,所谓”并“就是将选择区域与人脸区域两部分面积求和,然后减去重叠部分的面积,然后计算重叠部分面积占“并”后面积的比率,根据比率的大小来决定图片的属性,由此我们给出计算人脸所占区域比率的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def  IOU(box, boxes):

   box_area = (box[2] - box[0] + 1) * (box[3] - box[1] + 1)
   boxes_area = (boxes[:,2] - boxes[:,0] + 1) * (boxes[:,3] - boxes[:,1] + 1)

   #计算矩形重叠部分面积
   xx1 = np.maximum(box[0], boxes[: ,0])
   yy1 = np.maximum(box[1], boxes[:,1])
   xx2 = np.minimum(box[2], boxes[:,2])
   yy2 = np.minimum(box[3], boxes[:,3])

   w = np.maximum(0, xx2 - xx1 + 1)
   h = np.maximum(0, yy2 - yy1 + 1)
   over_lap = w * h
   area_combine = (box_area + boxes_area - over_lap + 1e-10) #1e-10避免数值为0
   overlap_percentage = over_lap / area_combine 

   return overlap_percentage

代码将两个区域的面积加总然后减去两个区域的重叠部分由此得到两个区域的“并后我们随机在图片上扣出一系列区域,然后选择那些与人脸区域交集所占比率小于0.3的区域作为训练数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npr=np.random
def  create_neg_parts(img, face_boxes):
  neg_num = 0
  height, width, channel = img.shape
  neg_boxes = []
  while neg_num < 50:
      #随机截取一个区域,不小于12*12,因为pnet要训练得识别12*12的图片内部是否有人脸
      size = npr.randint(12, min(width, height) / 2)
      #选取左上角坐标
      nx = npr.randint(0, width - size)
      ny = npr.randint(0, height - size)
      crop_box = np.array([nx, ny, nx+size, ny + size])
      iou = IOU(crop_box, face_boxes)

      if np.max(iou) < 0.3: #如果截取的面积与所有人脸面积重叠部分小于两者合并面积的0.3表明截取面积中不含有人脸
          neg_boxes.append(crop_box)
          neg_num += 1

  return  neg_boxes

def  draw_boxes(img, boxes, color):
    for box in boxes:
        top_left = (box[0], box[1])
        bottom_right = (box[2], box[3])
        img = cv2.rectangle(img, top_left, bottom_right, color, 1)
    cv2_imshow(img)

接着我们调用上面代码并将所选择的区域绘制出来,这样读者就能对算法和代码有更感性的理解:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
print(len(boxes))
color = (0, 255, 0)
neg_boxes = create_neg_parts(face_img, boxes)
draw_boxes(face_img.copy(), neg_boxes, color)

代码运行后所得结果如下:

注意到绿色方框所对应的区域要不完全不包含人脸,要不与人脸区域的交集所占比率少于0.3.为了让网络对人脸的识别能力更强,我们还需要构造一部分人脸区域所占比率接近0.3的图片,也就是图片中含有一小部分人脸,这种只包含部分人脸的图片对网络的训练效果最好,选取包含部分人脸图片的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def  create_neg_overlapped_parts(img, face_boxes): #产生只含有部分脸部的区域
    height, width, channel = img.shape
    neg_overlapped_boxes = []
    for box in face_boxes:
        left, top, right, bottom = box
        w = right - left
        h = bottom - top
        if max(w, h) < 20 or left < 0 or top < 0: #忽略掉小于20像素的人脸区域
            continue
        for i in range(5): #每个人脸区域最多生成5个重叠不超过0.3的区域
            size = npr.randint(12, min(width, height))
            delta_x = npr.randint(max(-size, -left), w) 
            delta_y = npr.randint(max(-size, -top), h) #沿着左上角随机上下和左右偏移形成重叠区域的左上角
            nx1 = int(max(0, left + delta_x))
            ny1 = int(max(0, top + delta_y))
            if nx1 + size > width or ny1 + size > height: #确保创建的区域不超过整个图片范围
                continue
            crop_box = np.array([nx1, ny1, nx1+size, ny1+size])
            iou = IOU(crop_box, face_boxes)
            if np.max(iou) < 0.3:
                neg_overlapped_boxes.append(crop_box)
    return  neg_overlapped_boxes

neg_overlapped_boxes = create_neg_overlapped_parts(face_img, boxes)
print(len(neg_overlapped_boxes))
color = (0, 0, 255)
draw_boxes(face_img.copy(), neg_overlapped_boxes, color)

上面代码运行后结果如下:

从上图看到红色方框就是代码选择的区域,这些区域与蓝色人脸区域都有重叠,同时重叠部分占两个区域面积的比率都少于03.接下来使用同样的方法产生性质为“part”和”post”的图片,这类图片包含一部分人脸,其中人脸所占图片比率在0.3和0.45之间,要不就占据比率超过0.65,而后者是被认为包含了人脸的图片,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def  create_pos_part_box(img, boxes): #产生与脸部重叠部分超过0.650.45的交集区域
    height, width, channel = img.shape
    pos_boxes = []
    pos_offset = []
    part_boxes = []
    part_offset = []
    for box in boxes:
        left, top, right, bottom = box
        w = right - left
        h = bottom - top
        if max(w, h) < 20 or left < 0 or top < 0:
            continue 
        for i in range(20): #每个人脸生成20个与人脸部分重叠超过0.650.4的区域
            size = npr.randint(int(min(w, h) * 0.8), np.ceil(1.25 * max(w, h)))
            if w < 5:
                continue
            delta_x = npr.randint(-w * 0.2, w * 0.2)
            delta_y = npr.randint(-h * 0.2, h * 0.2)
            nx1 = int(max(left + w /2 + delta_x - size / 2, 0))
            ny1 = int(max(top + h / 2 + delta_y - size / 2, 0))
            nx2 = nx1 + size
            ny2 = ny1 + size
            if nx2 > width or ny2 > height: # 生成区域不能超出图片大小
                continue
            crop_box = np.array([nx1, ny1, nx2, ny2])

            #计算生成区域左上角和右下角相对于人脸框的偏移比率后期计算需要
            offset_x1 = (left - nx1)/float(size)
            offset_y1 = (top - ny1) / float(size)
            offset_x2 = (right - nx2) / float(size)
            offset_y2 = (bottom - ny2) / float(size)
            box_ = box.reshape(1, -1)
            iou = IOU(crop_box, box_)

            if np.max(iou) >= 0.65:
                pos_boxes.append(crop_box)
                pos_offset.append((offset_x1, offset_y1, offset_x2, offset_y2))
            elif np.max(iou) >= 0.4:
                part_boxes.append(crop_box)
                part_offset.append((offset_x1, offset_y1, offset_x2, offset_y2))
    return pos_boxes, pos_offset, part_boxes, part_offset        

pos_boxes, pos_offset, part_boxes, part_offset = create_pos_part_box(face_img, boxes)
print("pos boxes len: ", len(pos_boxes))
print("part boxes len: ", len(part_boxes))
color = (125, 125, 0)
draw_boxes(face_img.copy(), pos_boxes, color) #显示与脸部重叠面积超过0.65的区域

上面代码运行后结果如下:

图片中绿色方框就是代码选择比率超过0.65的区域,注意到这些区域与蓝色方框对应的人脸区域有很大的重叠部分,我们再看看比率在0.3到0.45直接的区域:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
color = (0, 125, 125)
draw_boxes(face_img.copy(), part_boxes, color) #显示与脸部重叠面积超过0.4的区域

代码运行后所得结果如下:

我们将三部分数据分别存储在不同文件夹下,第一种存在”neg”文件夹,第二种存在”part”文件夹,第三种存在”pos”文件夹,然后就可以把他们当做训练数据输入网络。这些实践对理论的理解至关重要,如若不然你看论文描述的算法就会落入到云里雾里,这也是我认为很多知乎上的文章是装逼假把式的主要原因。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coding迪斯尼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Access数据库表字段属性(二)
大家好,上节介绍了字段属性中的输入掩码和格式,本节介绍验证规则和验证文本等。验证规则和Excel的有效性规则类似。
无言之月
2019/12/27
4.9K0
Access数据库表字段属性(三)
字段大小是文本、数字和自动编号等数据类型的字段,可以指定其字段的大小。【短文本】类型最长255个字符,如果超过255个字符,数据类型使用【长文本】。
无言之月
2020/01/14
2.9K0
Access数据库表字段属性(三)
Access数据库表初识
大家好,本节主要是通过Excel和Access表的简单对比,来了解Access中表的一些基本概念(对Access有基础的可以跳过)。
无言之月
2019/10/13
5.3K0
python手把手教你获取某月第一天和最后一天
python自带有很多跟时间计算的libraries。接下来介绍几种不同的方法来取得
mariolu
2023/11/30
3K0
Access数据库表字段类型
大家好,上节简单演示在Access数据库中创建对应的表的步骤。本节简单汇总下字段的数据类型,属性在下节介绍。
无言之月
2019/10/13
6.8K0
django 字段类型_access的数据库类型是
自增的整型字段,必填参数primary_key=True,则成为数据库的主键,无该字段时,django会自动创建主键id字段。
全栈程序员站长
2022/10/04
4.4K0
数据库之MySQL函数(二)
时间戳是一份能够表示一份数据在一个特定时间点已经存在的完整的可验证的数据。 5、转换时间戳的函数
小手冰凉
2020/04/26
13.5K0
数据库之MySQL函数(二)
MySQL数据库应用总结(六)—MySQL数据库的数据类型和运算符(上)
该文介绍了MySQL数据库中的一种特殊类型——枚举类型,并说明了在哪些场景下使用枚举类型比较合适。同时,介绍了在MySQL中枚举类型与枚举值的区别,以及枚举类型在SQL语句中的应用方法。
企鹅号小编
2018/01/02
3.5K0
MySQL数据库应用总结(六)—MySQL数据库的数据类型和运算符(上)
C# WPF Dev控件之正则验证介绍
WPF数据编辑器库附带的大多数文本编辑器(TextEdit子体)允许您在编辑期间使用掩码。掩码提供受限的数据输入和格式化的数据输出。
用户9127601
2022/03/23
2.1K0
C# WPF Dev控件之正则验证介绍
Access数据库相关知识
比如,公园到访者的数据表,可能包含的实体有:公园信息(主键是公园编号),到访者的信息(主键是到访者编号),到访者居住地的信息(主键是居住地编号)一共有2个实体,即3张表。
Sidchen
2020/08/07
4.1K0
常用的数据库的字段类型及大小比较_sql字段长度
ORACLE的数据类型 常用的数据库字段类型如下: 字段类型 中文说明 限制条件 其它说明 CHAR 固定长度字符串 最大长度2000 bytes ` VARCHAR2 可变长度的字符串 最大长度4000 bytes 可做索引的最大长度749 NCHAR 根据字符集而定的固定长度字符串 最大长度2000 bytes NVARCHAR2 根据字符集而定的可变长度字符串 最大长度4000 bytes DATE 日期(日-月-年) DD-MM-YY(HH-MI-SS) 经过严格测试,无千虫问题 LONG 超长字符串 最大长度2G(231-1) 足够存储大部头著作 RAW 固定长度的二进制数据 最大长度2000 bytes 可存放多媒体图象声音等 LONG RAW 可变长度的二进制数据 最大长度2G 同上 BLOB 二进制数据 最大长度4G CLOB 字符数据 最大长度4G NCLOB 根据字符集而定的字符数据 最大长度4G BFILE 存放在数据库外的二进制数据 最大长度4G ROWID 数据表中记录的唯一行号 10 bytes **.*.*格式,*为0或1 NROWID 二进制数据表中记录的唯一行号 最大长度4000 bytes NUMBER(P,S) 数字类型 P为整数位,S为小数位 DECIMAL(P,S) 数字类型 P为整数位,S为小数位 INTEGER 整数类型 小的整数 FLOAT 浮点数类型 NUMBER(38),双精度 REAL 实数类型
全栈程序员站长
2022/10/04
5K0
常用的数据库的字段类型及大小比较_sql字段长度
盘点MySQL数据库的数据类型、库和表常见操作、索引、视图、函数等知识点
在日常开发中,存储数据的最常用的方式便是数据库了,其中最为著名的便是MySQL数据库,因它简便易于上手而且可扩展性强大,跨平台使得它广为使用。上一篇文章,我们讲到了它的安装,今天我们就来具体聊聊它的这篇文章分为11个部分,分别包括MySQL数据库的数据类型、库和表常见操作、索引、视图、函数、游标、触发器、存储过程、事务、备份与还原、用户账号、其它等知识点。
前端皮皮
2021/10/08
1.8K0
MatLab函数datetime、datenum、datevec、datestr
datenum 函数用于将日期和时间转换成日期序列值,即将每个时间点表示为从 0000年 1月 0日起的天数。
hotarugali
2022/03/01
6.2K0
Java魔法堂:String.format详解
  目录                               一、前言 二、重载方法 三、占位符 四、对字符、字符串进行格式化 五、对整数进行格式化 六、对浮点数进行格式化 七、对日期时间进行格式化 八、其他转换符   九、总结   参考 一、前言                             String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.format("Hello %s", "John"
^_^肥仔John
2018/01/18
2K0
深度学习之主流数据库 | MySQL基础
这篇文章主要是讲一下常见的MySQL的安装,和基本操作。适合完全没有MySQL知识但是又急需一些MySQL知识的童靴作为快速入门使用。 背景与安装 背景不用多说了,大家都懂得。直接说在Ubuntu下面的安装吧。其实也是很简单。这里不搞复杂的源码安装,就依次输入下面非常简单的命令安装就够了。 sudo apt-get install mysql-server sudo apt isntall mysql-client sudo apt install libmysqlclient-dev 中间会有弹出设置
用户1332428
2018/03/09
2K0
深度学习之主流数据库 | MySQL基础
进阶数据库系列(六):PostgreSQL 数据类型与运算符
PostgreSQL 支持多种数据类型,主要有整数类型、浮点数类型、任意精度数值、日期/时间类型、字符串类型、二进制类型、布尔类型和数组类型等。
民工哥
2023/08/22
6.9K0
进阶数据库系列(六):PostgreSQL 数据类型与运算符
MySQL从删库到跑路(三)——SQL语言
SQL是结构化查询语言(Structured Query Language),是用于访问和处理数据库的标准的计算机语言。 SQL语言的功能如下: A、SQL面向数据库执行查询 B、SQL可从数据库取回数据 C、SQL可在数据库中插入新的记录 D、SQL可更新数据库中的数据 E、SQL可从数据库删除记录 F、SQL可创建新数据库 G、SQL可在数据库中创建新表 H、SQL可在数据库中创建存储过程 I、SQL可在数据库中创建视图 J、SQL可以设置表、存储过程和视图的权限 SQL是一门ANSI的标准计算机语言,用来访问和操作数据库系统。SQL语句用于取回和更新数据库中的数据。SQL可与数据库程序协同工作,比如MS Access、DB2、Informix、MS SQL Server、Oracle、MySQL、Sybase以及其他数据库系统。 每一种数据库有自己版本的SQL语言,但是为了与ANSI标准相兼容,SQL必须以相似的方式共同地来支持一些主要的关键词(比如 SELECT、UPDATE、DELETE、INSERT、WHERE等等)。 除了SQL标准之外,大部分SQL数据库程序都拥有自己的私有扩展。
良月柒
2019/03/19
1.9K0
数据库之数据类型详解
查看表的详细信息如下(在创建表的时候没有指定其长度,但是每一列都有自己默认的长度):
小手冰凉
2020/04/24
4.9K0
MatLab函数ylabel、ylim、yticks、yticklabels、ytickformat
【注】x、z 轴对应函数同理;具体函数详解在 MatLab 中使用命令 help func 查阅。
hotarugali
2022/02/28
3.5K0
MatLab函数ylabel、ylim、yticks、yticklabels、ytickformat
从零开发区块链应用(二)--mysql安装及数据库表的安装创建
数据类型是指列、存储过程参数、表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型。有一些数据是要存储为数字的,数字当中有些是要存储为整数、小数、日期型等...
Tiny熊
2022/02/22
1.5K0
推荐阅读
相关推荐
Access数据库表字段属性(二)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档