图像的翻转,仿射变换

文章目录

  • 图像的翻转,仿射变换
  • 图像去雾
  • 3D
  • 添加水印
    • 添加字体水印
    • 添加图片水印

图像的翻转,仿射变换

import cv2
import numpy as np
from matplotlib import pyplot as plt
import math
from skimage import util,color
import random
import datetime
import pywt

## for color image show with plt
'''
    cv读入图像与plt显示图像之间bgr->rgb的转换
'''
def img_plt(img):
    b,g,r = cv2.split(img)
    img = cv2.merge([r, g, b])
    return img

def img_translation(img,tx,ty):
    dst_img = np.zeros((img.shape),dtype='uint8')
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if i+tx<dst_img.shape[0] and j+ty<dst_img.shape[1]:
               dst_img[i+tx][j+ty] = img[i][j]
    return dst_img

def img_resize(img,sx,sy):
    if len(img.shape)<=2:
        dst_img = np.zeros((round(img.shape[0]*sx),round(img.shape[1]*sy)),dtype='uint8')
    else:
        dst_img = np.zeros((round(img.shape[0] * sx), round(img.shape[1] * sy),img.shape[2]), dtype='uint8')
    for i in range(dst_img.shape[0]):
        for j in range(dst_img.shape[1]):
            if round(i/sx) < img.shape[0] and round(j/sy) < img.shape[1]:
                dst_img[i][j] = img[round(i/sx)][round(j/sy)]
    return dst_img

def img_rotation(img,th):
    dst_img = np.zeros((img.shape), dtype='uint8')
    row = img.shape[0]
    col = img.shape[1]
    # x = x'cos(theta)-y'sin(theta) + m/2*(1-cos(theta))+n/2*sin(theta)
    # y = x'sin(theta)+y'cos(theta) + n/2*(1-cos(theta))-m/2*sin(theta)
    for i in range(row):
        for j in range(col):
            m = i*math.cos(th)-j*math.sin(th)+row/2*(1-math.cos(th))+col/2*math.sin(th)
            n = i*math.sin(th)+j*math.cos(th)+col/2*(1-math.cos(th))-row/2*math.sin(th)
            if m >=0 and m < row and n >=0 and n<col:
                dst_img[i][j] = img[math.floor(m)][math.floor(n)]
    return dst_img

# 最近邻插值算法
# dst_h为新图的高;dst_w为新图的宽
def NN_interpolation(img,dst_h,dst_w):
    scr_h = img.shape[0]
    scr_w = img.shape[1]
    if len(img.shape)>2:
        dst_img=np.zeros((dst_h,dst_w,img.shape[2]),dtype=np.uint8)
    else:
        dst_img = np.zeros((dst_h, dst_w), dtype=np.uint8)
    for i in range(dst_h):
        for j in range(dst_w):
            scr_x=round(i*(scr_h/dst_h))
            scr_y=round(j*(scr_w/dst_w))
            if scr_x < scr_h and scr_y < scr_w:
                dst_img[i,j]=img[scr_x,scr_y]
    return dst_img

## 双线性插值
def bilinear_interpolation(img, dst_h,dst_w):
    src_h = img.shape[0]
    src_w = img.shape[1]
    if src_h == dst_h and src_w == dst_w:
        return img.copy()
    if len(img.shape) > 2:
        dst_img = np.zeros((dst_h, dst_w, img.shape[2]), dtype=np.uint8)
    else:
        dst_img = np.zeros((dst_h, dst_w), dtype=np.uint8)
    scale_x, scale_y = float(src_h) / dst_h, float(src_w) / dst_w
    for dstx in range(dst_h):
        for dsty in range(dst_w):

            # find the origin x and y coordinates of dst image x and y
            # use geometric center symmetry
            # if use direct way, src_x = dst_x * scale_x
            srcy = (dsty + 0.5) * scale_y - 0.5  # yp  y'
            srcx = (dstx + 0.5) * scale_x - 0.5  # xp  x'

            # find the coordinates of the points which will be used to compute the interpolation
            src_y0 = int(math.floor(srcy))       # j
            src_y1 = min(src_y0 + 1, src_w - 1)   # j+1
            src_x0 = int(math.floor(srcx))       # i
            src_x1 = min(src_x0 + 1, src_h - 1)   # i+1
            ##  A(i,j) B(i+1,j)  C(i,j+1)  D(i+1,j+1)
            if src_x0 != src_x1 and src_y1 != src_y0:
                ### calculate the interpolation
                ge = ((src_x1 - srcx) * img[src_x0, src_y0] + (srcx - src_x0) * img[src_x1, src_y0]) / (src_x1 - src_x0)
                gf = ((src_x1 - srcx) * img[src_x0, src_y1] + (srcx - src_x0) * img[src_x1, src_y1] )/ (src_x1 - src_x0)
                dst_img[dstx, dsty] = ((src_y1 - srcy) * ge + (srcy - src_y0) * gf) / (src_y1 - src_y0)
    return dst_img

if __name__ == '__main__':
    #####  Image correction
    ### warpAffine
    # cv2.flip()                                   # 图像翻转
    # cv2.warpAffine()                             # 图像仿射
    # cv2.getRotationMatrix2D()                    #取得旋转角度的Matrix
    # cv2.GetAffineTransform(src, dst, mapMatrix)  #取得图像仿射的matrix
    # cv2.getPerspectiveTransform(src, dst)        #取得图像透视的4个点起止值
    # cv2.warpPerspective()                        #图像透视

    ###  Gray interpolation
    # img = cv2.imread('lena-color.jpg')
    # dst_NN = NN_interpolation(img, 1024,1024)
    # dst_bi = bilinear_interpolation(img, 1024,1024)
    # img = img_plt(img)
    # dst_NN = img_plt(dst_NN)
    # dst_bi = img_plt(dst_bi)
    # dif = dst_NN - dst_bi
    # plt.figure(1)
    # plt.subplot(221),plt.xlabel("original image"),plt.imshow(img)
    # plt.subplot(222),plt.xlabel("NN interpolation"), plt.imshow(dst_NN)
    # plt.subplot(223),plt.xlabel("Bilinear interpolation"), plt.imshow(dst_bi)
    # plt.subplot(224), plt.xlabel("Dif with NN and Bi"), plt.imshow(dif)
    # plt.show()
    ##### Image Inpaint with opencv
    ## get the mask image
    # img1 = cv2.imread('lena-color-need-process.png')
    # img2 = cv2.imread('lena-color.jpg')
    # mask_img = img1-img2
    # for i in range(mask_img.shape[0]):
    #     for j in range(mask_img.shape[1]):
    #         if mask_img[i,j,0] != 0 and mask_img[i,j,1] != 0 and mask_img[i,j,2] != 0:
    #             mask_img[i,j,:] = 255
    # cv2.imwrite('lena-color-mask.png',mask_img)
    #### image inpaint
    img1 = cv2.imread('lena-color-need-process.png')
    mask_img = cv2.imread('lena-color-mask.png')
    mask_img = cv2.cvtColor(mask_img, cv2.COLOR_BGR2GRAY)
    dst_TELEA = cv2.inpaint(img1, mask_img, 3, cv2.INPAINT_TELEA)
    dst_NS = cv2.inpaint(img1, mask_img, 3, cv2.INPAINT_NS)
    img1 = img_plt(img1)
    dst_TELEA = img_plt(dst_TELEA)
    dst_NS = img_plt(dst_NS)
    plt.figure(1)
    plt.xlabel("Image patching")
    plt.subplot(221),plt.xlabel("degraded image"),plt.imshow(img1)
    plt.subplot(222), plt.xlabel("mask image"), plt.imshow(mask_img,cmap = 'gray')
    plt.subplot(223),plt.xlabel("TELEA"),plt.imshow(dst_TELEA)
    plt.subplot(224), plt.xlabel("NS"), plt.imshow(dst_NS)


    img = cv2.imread('lena-color.jpg')
    img = img_plt(img)
    plt.figure(2)
    plt.imshow(img)  # 显示原图像
    plt.show()

图像去雾

import cv2
import numpy as np
from matplotlib import pyplot as plt
import math


###  最小值滤波,r是滤波器半径
def zmMinFilterGray(src, r=7):
    ###  腐蚀操作  模板中心点的像素值为:模板覆盖区域内所有像素中的最小的值
    return cv2.erode(src, np.ones((2 * r + 1, 2 * r + 1)))

###  基于引导滤波的大气光估计,I输入暗通道图像,p引导图像为,eps精度参数
def guidedfilter(m,I, p, r, eps):
    height, width = I.shape
    m_I = cv2.boxFilter(I, -1, (r, r))        ## 线性滤波器:默认均值滤波
    m_p = cv2.boxFilter(p, -1, (r, r))
    m_Ip = cv2.boxFilter(I * p, -1, (r, r))
    cov_Ip = m_Ip - m_I * m_p

    m_II = cv2.boxFilter(I * I, -1, (r, r))
    var_I = m_II - m_I * m_I

    a = cov_Ip / (var_I + eps)
    b = m_p - a * m_I

    m_a = cv2.boxFilter(a, -1, (r, r))
    m_b = cv2.boxFilter(b, -1, (r, r))
    V1 = m_a * I + m_b

    ### 计算大气光照A
    bins = 2000
    ht = np.histogram(V1, bins)                  # histogram
    d = np.cumsum(ht[0]) / float(V1.size)        # Cumulative histogram
    for lmax in range(bins - 1, 0, -1):
        if d[lmax] <= 0.999:
            break
    A = np.mean(m, 2)[V1 >= ht[1][lmax]].max()  #依据V1,估计大气光值

    return V1,A         #滤波输出图像 通过引导滤波得到的大气耗散 V(x)模糊版本

###  w透射率权重  maxV1灰度最大值
def Defog(m, r, eps, w, maxV1):                 # 输入rgb图像,值范围[0,1]
    ###计算大气遮罩图像V1和光照值A, V1 = 1-t/A
    V1 = np.min(m, 2)                           # 得到暗通道图像

    Dark_Channel = zmMinFilterGray(V1, 7)      #  最小值滤波

    V1,A = guidedfilter(m,V1, Dark_Channel, r, eps)  # 使用引导滤波优化

    V1 = np.minimum(V1 * w, maxV1)               # 对值范围进行限制
    return V1, A

###
###  r 代表反射率
def deHaze(m, r=81, eps=0.001, w=0.95, maxV1=0.80, bGamma=False):
    Y = np.zeros(m.shape)
    Mask_img, A = Defog(m, r, eps, w, maxV1)             # 得到遮罩图像和大气光照

    for k in range(3):
        Y[:,:,k] = (m[:,:,k] - Mask_img)/(1-Mask_img/A)  # 颜色校正
    Y = np.clip(Y, 0, 1)
    if bGamma:
        Y = Y ** (np.log(0.5) / np.log(Y.mean()))       # gamma校正,默认不进行该操作
    return Y

## for color image show with plt
def img_plt(img):
    b,g,r = cv2.split(img)
    img = cv2.merge([r, g, b])
    return img

if __name__ == '__main__':
    img = cv2.imread('fog0.jpg')
    m = np.uint8(deHaze(img / 255.0) * 255)  # deHaze输入值范围[0,1]

    plt.subplot(121),plt.imshow(img)
    plt.title('Input Image'), plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.imshow(m)
    plt.title('Defog result'), plt.xticks([]), plt.yticks([])
    plt.show()

3D

import numpy as np
import pandas as pd
import cv2
import numpy as np
from skimage.draw import ellipsoid
import matplotlib.pyplot as plt
from skimage import measure, morphology
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

if __name__ == '__main__':
    # Generate a level set about zero of two identical ellipsoids in 3D
    ellip_base = ellipsoid(6, 10, 16, levelset=True)
    ellip_double = np.concatenate((ellip_base[:-1, ...],
                                   ellip_base[2:, ...]), axis=0)

    # Use marching cubes to obtain the surface mesh of these ellipsoids
    verts, faces, normals, values = measure.marching_cubes_lewiner(ellip_double, 0)

    # Display resulting triangular mesh using Matplotlib. This can also be done
    # with mayavi (see skimage.measure.marching_cubes_lewiner docstring).
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')

    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    mesh = Poly3DCollection(verts[faces])
    mesh.set_edgecolor('k')
    ax.add_collection3d(mesh)

    ax.set_xlabel("x-axis: a = 6 per ellipsoid")
    ax.set_ylabel("y-axis: b = 10")
    ax.set_zlabel("z-axis: c = 16")

    ax.set_xlim(0, 24)  # a = 6 (times two for 2nd ellipsoid)
    ax.set_ylim(0, 20)  # b = 10
    ax.set_zlim(0, 32)  # c = 16

    plt.tight_layout()
    plt.show()

图像的翻转,仿射变换_第1张图片

添加水印

添加字体水印

import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image, ImageDraw, ImageFont

####水印
###添加字体
# im = Image.open("lena-color.jpg").convert('RGBA')
# #新建一个空白图片,尺寸与打开图片一样
# txt=Image.new('RGBA', im.size, (0,0,0,0))
# #设置字体
# fnt=ImageFont.truetype("c:/Windows/Fonts/Tahoma.ttf", 40)
# #操作新建的空白图片>>将新建的图片添入画板
# d=ImageDraw.Draw(txt)
# #在新建的图片上添加字体
# d.text((txt.size[0]-115,txt.size[1]-80), "cnBlogs",font=fnt, fill=(255,255,255,50))
# #合并两个图片
# out=Image.alpha_composite(im, txt)
# out.show()

def add_text_to_image(image, text):
    font = ImageFont.truetype('C:\Windows\Fonts\STXINGKA.TTF', 36)

    # 添加背景
    new_img = Image.new('RGBA', (image.size[0] * 3, image.size[1] * 3), (0, 0, 0, 0))
    new_img.paste(image, image.size)

    # 添加水印
    font_len = len(text)
    rgba_image = new_img.convert('RGBA')
    text_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0))
    image_draw = ImageDraw.Draw(text_overlay)  ##创建一个可以在给定图像上绘图的对象
# 多水印添加
    for i in range(0, rgba_image.size[0], font_len * 40 + 100):
        for j in range(0, rgba_image.size[1], 200):
            ####
            image_draw.text((i, j), text, font=font, fill=(0, 0, 0, 50))
    text_overlay = text_overlay.rotate(-45)     ##方向
    image_with_text = Image.alpha_composite(rgba_image, text_overlay)

    # 裁切图片
    image_with_text = image_with_text.crop((image.size[0], image.size[1], image.size[0] * 2, image.size[1] * 2))
    return image_with_text


if __name__ == '__main__':
    img = Image.open("lena-color.jpg")
    im_after = add_text_to_image(img, '测试使用')
    im_after.show()


添加图片水印

##添加小图片水印
im = Image.open("lena-color.jpg")
mark=Image.open("mask.jpg")
layer=Image.new('RGBA', im.size, (0,0,0,0))
##paste函数的参数为(需要修改的图片,粘贴的起始点的横坐标,粘贴的起始点的纵坐标)
layer.paste(mark, (int(im.size[0]/3),int(im.size[1]/3)))
out=Image.composite(layer,im,layer)
out.show()

# PIL的alpha_composite(im1,im2) 图像通道融合
# im2要和im1的size和mode一致,且要求格式为RGBA
im1 = Image.open("lena-color.jpg")
im2 = Image.open("mask.jpg")
layer=Image.new('RGBA', im1.size, (0,0,0,0))
layer.paste(im2, (int(im1.size[0]/3),int(im1.size[1]/3)))
im1=im1.convert("RGBA")
newim1 = Image.alpha_composite(im1,layer) # 将im2合成到im1中,如果其一是透明的,
# 才能看到结果,不然最终结果只会显示出im2
newim1.show()
#print(im1.mode)

# -----------------------------------------
# image.blend(im1,im2,alpha)
# alpha为透明度
newim2 = Image.blend(im1,layer,0.5)
newim2.show()

####  视频处理
vidcap = cv2.VideoCapture('test.mov')
#获得码率及尺寸
fps = vidcap.get(cv2.CAP_PROP_FPS)
size = (int(vidcap.get(cv2.CAP_PROP_FRAME_WIDTH)),
        int(vidcap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
count = 0
# cv2.namedWindow('input_image', cv2.WINDOW_AUTOSIZE)
success,image = vidcap.read()
while success:
  # cv2.imshow('frame',image)
  # cv2.waitKey(0)
  cv2.imwrite("./frame/frame%d.jpg" % count, image)  # save frame as JPEG file
  if cv2.waitKey(10) == 27:
      break
  count += 1
  success, image = vidcap.read()
# cv2.destroyAllWindows()

# 高斯金字塔
def pyramid_image(image):
    level = 3  # 金字塔的层数
    temp = image.copy()  # 拷贝图像
    pyramid_images = []
    for i in range(level):
        dst = cv2.pyrDown(temp)
        pyramid_images.append(dst)
        cv2.imshow("gussian" + str(i), dst)
        temp = dst.copy()
    return pyramid_images


# 拉普拉斯金字塔
def laplian_image(image):
    pyramid_images = pyramid_image(image)
    level = len(pyramid_images)
    for i in range(level - 1, -1, -1):
        if (i - 1) < 0:
            expand = cv2.pyrUp(pyramid_images[i], dstsize=image.shape[:2])
            lpls = cv2.subtract(image, expand)
            cv2.imshow("lap" + str(i), lpls)
        else:
            expand = cv2.pyrUp(pyramid_images[i], dstsize=pyramid_images[i - 1].shape[:2])
            lpls = cv2.subtract(pyramid_images[i - 1], expand)
            cv2.imshow("lap" + str(i), lpls)


src = cv2.imread("lena-color.jpg")
cv2.imshow("input image", src)
pyramid_image(src)
# laplian_image(src)
cv2.waitKey(0)
cv2.destroyAllWindows()

你可能感兴趣的:(数字图像处理)