环形文字拉直的两种方法:极坐标转换和薄板样条插值python代码示例

该博客探讨了两种环形文字识别的方法:极坐标转换和薄板样条插值法。方案一利用numpy实现从极坐标到直角坐标的转换,适用于圆和椭圆的文字;方案二采用OpenCV的warpPolar函数及 ThinPlateSplineShapeTransformer进行图像变形,适合复杂形状的文字处理。这两种技术在图像预处理中对于提高环形文字的识别率至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言
  • 针对环形文字识别,通过这几天调研,一般有两种方法,一是极坐标转换;二是薄板样条插值(TPS)法。
极坐标转换
方案一:
import numpy as np


def circle_to_rectangle(cir_img, start=0):
    """
    对圆和椭圆的旋转文字进行极坐标到直角坐标转换
    默认从正下方开始切,可以通过start设定偏移角度,单位为度
    """
    h, w = cir_img.shape[:2]
    x0, y0 = h // 2, w // 2  # TODO: ????不明白为啥h w反了
    radius = (x0 + y0) // 2  # 兼顾圆和椭圆
    rect_height = radius  # 要切的厚度
    rect_width = int(2 * np.pi * radius)  # 展开之后的周长
    rect_img = np.zeros((rect_height, rect_width, 3), dtype="u1")

    index_w = np.array(range(rect_width))
    index_h = np.array(range(rect_height))
    theta_array = 2 * np.pi * (index_w / rect_width + start / 360)

    for j, theta in zip(index_w, theta_array):
        x = x0 + (x0 - index_h) * np.cos(theta)
        y = y0 + (y0 - index_h) * np.sin(theta)

        x = np.where(x >= h, h - 1, x).astype(np.int16)
        y = np.where(y >= w, w - 1, y).astype(np.int16)

        rect_img[index_h, j, :] = cir_img[x, y, :]

    # 纠正水平镜像
    rect_img = np.fliplr(rect_img)
    return rect_img
方案二:
  • 代码出处:cv-warpPolar-example
    image = cv.imread('image.jpg')
    h, w = image.shape[:2]
    
    center = (round(w / 2), round( h / 2))
    flags = cv.INTER_CUBIC + cv.WARP_FILL_OUTLIERS + cv.WARP_POLAR_LINEAR
    radius = center[0]
    img_res  = cv.warpPolar(image, (300, 600), center, radius, flags)
    img_res = img_res.transpose(1,0,2)[::-1]
    
    img_res = cv2.cvtColor(img_res, cv2.COLOR_BGR2RGB)
    plt.imshow(img_res)
    plt.show()
    
  • 示例图(image.jpg):
    请添加图片描述
  • 结果图
    请添加图片描述
薄板样条插值法
  • 代码示例:(出处:暂时找不到了,作者如果看到,请联系我)
    # pip install opencv-contrib-python==4.5.5.64
    import cv2
    import numpy as np
    
    
    def tps_cv2(source, img):
        """
        source: list [(x0, y0), (x1, y1), (x2, y2), ...]
        """
        if isinstance(source, list):
            source = np.array(source)
    
        tps = cv2.createThinPlateSplineShapeTransformer()
    
        source_cv2 = source.reshape(1, -1, 2)
    
        matches = list()
        for i in range(len(source_cv2[0])):
            matches.append(cv2.DMatch(i, i, 0))
    
        new_points = []
        N = len(source)
        N = N // 2
        h, w = img.shape[:2]
        dx = int(w / (N - 1))  # 将w分成N份,每份是dx
        # 这里产生的是上部分的点
        for i in range(N):
            new_points.append((dx * i, 2))
    
        # 这里产生的是下部分的点
        for i in range(N - 1, -1, -1):
            new_points.append((dx * i, h - 2))
    
        target_cv2 = np.array(new_points, np.int32)
        target_cv2 = target_cv2.reshape(1, -1, 2)
    
        tps.estimateTransformation(target_cv2, source_cv2, matches)
        new_img_cv2 = tps.warpImage(img)
    
        return new_img_cv2
    
    source = [[217, 135], [302, 89], [419, 56], [589, 58], [716, 88], 
              [815, 131], [789, 180], [697, 144], [578, 116], [426, 116], 
              [320, 149], [245, 183]]
    
    img = cv2.imread('tps_img.jpeg')
    new_img = tps_cv2(source, img)
    cv2.imwrite('res_tps_img.jpeg', new_img)
    
  • 示例图(tps_img.jpeg
    请添加图片描述
  • 结果图(res_tps_img.jpeg
    请添加图片描述
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值