如何从OpenCV WarpAffine旋转中消除黑色像素行 [英] How to eliminate row of black pixels from OpenCV WarpAffine rotation

查看:212
本文介绍了如何从OpenCV WarpAffine旋转中消除黑色像素行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用cv2.warpAffine()将3张图像旋转180度,然后使用cv2.hconcat()将它们水平连接.这在图像之间添加了一个1像素宽的黑色列,但是img.shape中的图像宽度是正确的.如果我不旋转它们,则图像看起来不错,没有黑色的列.所有3张图像均为1920宽x 1200高.

I am rotating an 3 images 180 degrees with cv2.warpAffine() and then horizontally concatenating them with cv2.hconcat(). This is adding a 1 pixel wide column of black between the images but the width of the image from img.shape is correct. If I do not rotate them the image looks good with no black columns. All 3 images are 1920 wide x 1200 high.

如何消除黑柱?它类似于- warpAffine

How can I eliminate the black column? It is similar to - warpAffine

Scipy不会发生这种情况.被注释掉的代码(ndimage.rotate())是我如何使用Scipy解决的-从这里

It is not happening with Scipy. The commented out code (ndimage.rotate()) is how I solved it with Scipy - from here here. The Scipy code is slower and I have thousands of images.

编辑

一分钟后,我现在使用numpy只是将矩阵旋转90度两次.来自 numpy.rot90()这似乎更快.它也在下面的注释代码中.对于非90度角,我会坚持使用opencv的warpAffine.

After a minute I am now using numpy just to rotate the matrix 90 degrees twice. From numpy.rot90() This seems even faster. It is also in the commented code below. For non-90 degree angles, I'll stick with the warpAffine from opencv.

import cv2
import numpy as np
from scipy import ndimage


def rotate_image(mat, angle):     
    """   Rotates an image (angle in degrees) and expands image to avoid cropping
    """
    height, width = mat.shape[:2] # image shape has 3 dimensions
    image_center = (width/2, height/2) # getRotationMatrix2D needs coordinates in reverse order (width, height) compared to shape

    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0000)

    # rotation calculates the cos and sin, taking absolutes of those.
    abs_cos = abs(rotation_mat[0,0]) 
    abs_sin = abs(rotation_mat[0,1])

    # find the new width and height bounds
    bound_w = int(height * abs_sin + width * abs_cos)
 
    bound_h = int(height * abs_cos + width * abs_sin)
    
   
    # find the new width and height bounds
    bound_w = int(height * abs_sin + width * abs_cos)    
    bound_h = int(height * abs_cos + width * abs_sin)
    print(f'Bounds w = {bound_w} Bound H = {bound_h}')
    # subtract old image center (bringing image back to original) and adding the new image center coordinates
    rotation_mat[0, 2] += bound_w/2 - image_center[0]
    rotation_mat[1, 2] += bound_h/2 - image_center[1]
  

    # rotate image with the new bounds and translated rotation matrix
    rotated_mat = cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h))
    return rotated_mat

left_img = cv2.imread(r"F:\Basler\1595525164.242553_l.tiff",0)
cent_img = cv2.imread(r"F:\Basler\1595525164.242553_c.tiff",0)
rigt_img = cv2.imread(r"F:\Basler\1595525164.242553_r.tiff",0)
print(f'Shape = {rigt_img.shape} is {len(rigt_img.shape)}')

angle = 180


left_rot = rotate_image(left_img, angle)
cent_rot = rotate_image(cent_img, angle)
rigt_rot = rotate_image(cent_img, angle)
'''
left_rot = ndimage.rotate(left_img, angle)
cent_rot = ndimage.rotate(cent_img, angle)
rigt_rot = ndimage.rotate(rigt_img, angle)

THIS SEEMS THE FASTEST
left_rot = np.rot90(left_img,2)
cent_rot = np.rot90(cent_img,2)
rigt_rot = np.rot90(rigt_img,2)
'''
#lane_img = np.concatenate((left_rot, cent_rot, rigt_rot), axis=1)
lane_img = cv2.hconcat([left_rot, cent_rot, rigt_rot])
print(f'Size = {lane_img.shape}')
cv2.imwrite(r'C:\Users\Cary\Desktop\Junk\lane1.tiff', lane_img)

推荐答案

可以使用copyMakeBorder在旋转之前通过在图像的每一侧添加一条额外的线来删除该行:

The line can be removed by adding one additional line each side of image prior to rotation using copyMakeBorder:

after_mat = cv2.copyMakeBorder(
        mat,
        top=1,
        bottom=1,
        left=1,
        right=1,
        borderType=cv2.BORDER_REFLECT
    )

# rotate image with the new bounds and translated rotation matrix
rotated_mat = cv2.warpAffine(after_mat, rotation_mat, (bound_w, bound_h))

我不知道增加这行代码的原因(也许是由于旋转引起的移位?),但是上面的代码可以抑制它,希望没有副作用.

I don't know the cause of the additional line (maybe a shift due to rotation?), but code above can suppress it, hopefully without side effects.

这篇关于如何从OpenCV WarpAffine旋转中消除黑色像素行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆