数字图像处理作业

 要求:


本作业提供三个参考代码,在理解三个代码基础上,结合作业需求,将三个代码的工作整合、得到本次作业结果。

编程作业需要同学提供(1)实现编程任务对应的完整代码的.py文件;
(2)作业所需图像应以相对路径访问。
(3)作业运行结果截图,复制到提交作业区
 
本次作业的目的:
1. 基于python,实现在指定文件夹内包含人脸区域的图像文件的读取、图像可视化、保存、基本信息获取
2. 理解仿射变换的原理,能基于得到的匹配点对,估计两图像坐标系之间的仿射变换模型
3. 利用仿射变换,从每一幅输入图像中产生经过裁剪与几何校正的人脸输出图像。
 
 
请按照如下过程,完成指定工作任务。
1.   指定包含不同图像文件的输入文件夹,获取该文件夹下指定文件后缀名的图像文件列表,并且每幅图像中应含人脸区域。
2.   假设所有的裁剪、几何校正后的人脸输出图像都是200宽*200高
并且,左眼、右眼、嘴巴中心的(横,纵)坐标分别为:
(50,60)、(150,60)、(100,150)
3.   人脸区域的裁剪与几何校正。从每一幅图像中提取一个人脸区域并校正,具体流程如下:
遍历文件列表:
(1)获取列表中每个图像文件名
(2)读取每个图像文件,获取该图像的行数、列数、颜色通道数目
(3)显示图像
(4)在图像显示窗口,通过人机交互方式,借助鼠标点击,按照统一顺序(左眼、右眼、嘴巴),获取三个面部特征点在输入图像中的位置(横坐标,纵坐标),构成输入点集;
(5)以目标输出图像(200宽*200高)的左眼、右眼、嘴巴中心的(横,纵)坐标(50,60)、(150,60)、(100,150)构成输出点集;
(6)利用输入、输出点集,估计输入图像与输出图像的仿射变换模型;
(7)基于该变换模型,产生裁剪与校正后的输出人脸图像(200宽*200高),要求选择灰度插值方式为“双三次插值”;
(8)可视化输出的人脸图像;
(9)设置合适的规则,自动保存该图像至输出文件夹。

最好的作业应含:(1)输入图像所在文件夹;(2)输出图像文件夹;以及(3)运行代码.有关获取文件列表、人机交互获取图像像素坐标、仿射变换等简单代码可参见所附样例

# -*- coding: utf-8 -*-
"""
Created on Tue Mar 14 19:06:23 2023

@author: 鸭鸭爱吃辣
"""

import cv2
import numpy as np
import matplotlib.pyplot as plt
import skimage.io as io
from collections import Counter
from PIL import Image
import math
import os

dataset_dir = 'in' #输入文件夹
output_dir = 'out' #输出文件夹 (请自行修改为自己的地址)
image_filenames = [(os.path.join(dataset_dir, x), os.path.join(output_dir, x))
                    for x in os.listdir(dataset_dir)] #path[0]为图片地址,path[1]为输出地址(名字对应)

print('图片的文件名:',end=' ')
for path in image_filenames:
    print(path[0],end='\t')
    
#读取相应图像文件,获取对应图像的行数、列数、颜色通道数目
def get_red(img):
    redImg = img[:,:,2]
    return redImg

def get_green(img):
    greenImg = img[:,:,1]
    return greenImg

def get_blue(img):
    blueImg = img[:,:,0]
    return blueImg

print("\n图像的行数、列数、颜色通道数目:")
for path in image_filenames:
    img = cv2.imread(path[0])
    print(img.shape[:2])
    print(get_red(img)+get_green(img)+get_blue(img))
    print('\n')
    
print("显示原始输入图像:")
for path in image_filenames:
    img = cv2.imread(path[0])[:,:,(2,1,0)]
    plt.imshow(img)
    plt.axis('off')
    plt.show()


#定义左键点击事件响应函数
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
    global input_list
    a = len(input_list)
    if event == cv2.EVENT_LBUTTONDOWN:
        input_list.append([x,y])
        cv2.circle(img, (x, y), 3, (255, 0, 0), thickness = -1)
        cv2.putText(img, str(a+1), (x, y), cv2.FONT_HERSHEY_PLAIN,
                    1.0, (0,255,0), thickness = 1)
        cv2.imshow("window 2", img)

#获取三个输入点集
for path in image_filenames:
    img0 = cv2.imread(path[0])
    img = img0.copy()

    input_list = list()
    cv2.namedWindow("window 1",flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
    cv2.imshow("window 1", img0)
    
    
    cv2.namedWindow("window 2",flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
    cv2.imshow("window 2", img)
    cv2.setMouseCallback("window 2", on_EVENT_LBUTTONDOWN)
    while(1):
        if cv2.waitKey(0): # 按ESC键,循环终止,释放所有窗口资源
            break
    
    
    cv2.destroyAllWindows() #关闭窗口

    img = cv2.imread(path[0])

    rows, cols = img.shape[:2]

    pts_o = np.float32(input_list[:3])  # 这三个点为原始图片上数独的位置(切片防止多点误差)

    pts_d = np.float32([[50, 60], [150, 60], [100, 150]])  # 这是变换之后的图上三个点的位置

    M = cv2.getAffineTransform(pts_o, pts_d)

    dst = cv2.warpAffine(img, M=M, dsize=(200, 200), flags=cv2.INTER_CUBIC)  # 最后一参数是插值方式。

    cv2.imshow('img', img)

    cv2.imshow('dst', dst)
    # cv2.imwrite("./in/1.png".format(len(dst)), dst)
    #im = Image.fromarray(dst)(导出图片方式,尝试多次图片还是偏蓝)
    dst = Image.fromarray(dst.astype('uint8')).convert('RGBA')
    dst.save(path[1])
    cv2.waitKey(0)



#代码为作业示例

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值