Beispiel #1
0
def build_perspective_move_map(row, col, ratio_col_t, ratio_row, ratio_col_d):
    '''
    # row:高度
    # col:寬度
    # ratio_col_t:上邊縮小的比率,可以用0.85
    # ratio_row  :高度縮小的比率,可以用0.95
    # ratio_col_d:下邊縮小的比率,可以用0.95
    '''
    ### 注意這邊(0,0)是用圖的中心當原點,不是圖的左上角喔!
    x, y = get_xy_map(row, col)
    x = x - int(col / 2)
    y = y - int(row / 2)

    persp_row = row * ratio_row / 2  ### 下方 y方向的縮小比率
    persp_y = y * ratio_row  ### 下方 透射後的y座標


    ratio_col = ratio_col_t * (persp_row - persp_y) / (persp_row * 2)  +  \
                ratio_col_d * (persp_y  - (-int(row / 2) * ratio_row)) / (persp_row * 2)    ### x方向的縮小比率,這事會隨y而變化的,看筆記的圖才好理解喔!
    persp_x = x * ratio_col  ### 透射後的x座標

    move_x = persp_x - x  ### 原x座標怎麼位移到透射
    move_y = persp_y - y  ### 原y座標怎麼位移到透射
    move_map = np.dstack(
        (move_x, move_y))  ### 我move_map個格式就是shape=(row, col, 2),所以拼起來一下囉!
    return move_map
def apply_move_to_rec_tf(dis_img, move_map, max_db_move_x, max_db_move_y):
    max_db_move_x = tf.convert_to_tensor(max_db_move_x, dtype=tf.float32)
    max_db_move_y = tf.convert_to_tensor(max_db_move_y, dtype=tf.float32)
    # move_map   = tf.convert_to_tensor(move_map,dtype=tf.float32)

    row, col = move_map.shape[:2]  ### 256, 256
    go_x, go_y = get_xy_map(row, col)

    ### 注意,無法用 move_map[...,0]=... 的寫法,好像是 不能 單格指定值給 tensor裡的元素, 只能 整個tensor一起給值,
    # 所以才分成下三行 造出 整體要操作的tensor 再一起操作喔!
    x_move = move_map[..., 0] + go_x + max_db_move_x
    y_move = move_map[..., 1] + go_y + max_db_move_y
    xy_move = tf.stack((x_move, y_move), axis=2)
    move_map += xy_move  ### 整包加進去~
    move_map = tf.cast(move_map, tf.int32)

    ### tensor沒有辦法 像numpy 一樣靈活 用 array[ [1,3,5,...] ] 這種用法,所以要用 tf.numpy_function,把tensor轉成 numpy處理囉!
    rec_img = tf.numpy_function(fun, [dis_img, move_map], tf.float32)

    # print(type(dis_img),dis_img.dtype)
    # print(type(move_map),move_map.dtype)
    # print(type(max_db_move_x),max_db_move_x.dtype)
    # print(type(max_db_move_y),max_db_move_y.dtype)
    # print(type(dis_img),dis_img.dtype)
    # print(type(move_map),move_map.dtype)
    # print(type(row))
    # print(type(col))
    # print(type(go_x),go_x.dtype)
    # print(type(go_y),go_y.dtype)
    # print(type(x_move),y_move.dtype)
    # print(type(y_move),y_move.dtype)
    return rec_img
Beispiel #3
0
    def build_page_move_x(row, col, lr_shift=5):
        width = col
        height = row
        x, y = get_xy_map(row, col)

        ### 公式推倒過程看筆記
        m = (-lr_shift - lr_shift) / width
        z = m * x + lr_shift
        return z
def apply_move_to_rec2(dis_img, move_map, max_db_move_x, max_db_move_y):
    # start_time = time.time()
    dis_row, dis_col = dis_img.shape[:2]  ### 原始的 5xx, 5xx,不是512, 512喔!
    row, col = move_map.shape[:2]  ### 256, 256

    rec_img = np.zeros(shape=(row, col, 3),
                       dtype=np.uint8)  ### 建立存恢復影像的畫布,256,256
    go_x, go_y = get_xy_map(row, col)
    proc_move_map = move_map.copy()
    proc_move_map[..., 0] += go_x + max_db_move_x
    proc_move_map[..., 1] += go_y + max_db_move_y
    proc_move_map = proc_move_map.astype(np.int32)

    over_bound_msk = np.zeros(shape=(row, col),
                              dtype=np.uint8)  ### 用一個mask紀錄哪些pixel超出邊界
    over_bound_msk[
        proc_move_map[..., 0] >=
        dis_col] = 1  ### 只需=1即可,覺得不需要+=1,因為不需要 區分 x超過、y超過 還是 xy都超過,只要超過就算超過
    over_bound_msk[proc_move_map[..., 0] < dis_col * -1] = 1
    over_bound_msk[proc_move_map[..., 1] >= dis_row] = 1
    over_bound_msk[proc_move_map[..., 1] < dis_col * -1] = 1

    ### 修整move_map
    proc_move_map[proc_move_map[..., 0] >= dis_col,
                  0] = dis_col - 1  ### 太大超出邊界,設定成邊界
    proc_move_map[proc_move_map[..., 1] >= dis_row,
                  1] = dis_row - 1  ### 太大超出邊界,設定成邊界
    proc_move_map[proc_move_map[..., 0] < dis_col * -1, 0] = 0  ### 太小超出篇界,設定成0
    proc_move_map[proc_move_map[..., 1] < dis_col * -1, 1] = 0  ### 太小超出篇界,設定成0
    # np.save("proc_move_map_clip",proc_move_map)
    # cv2.imwrite("dis_img.bmp",dis_img)

    rec_img = dis_img[proc_move_map[..., 1],
                      proc_move_map[..., 0], :]  ### 用修整後的move_map回復影像

    ### 如果 move_map 本身的值已經爆掉了,那rec_img的該點就填0~ 這樣做沒問題!注意我現在是用 move_map 回去 dis_img找顏色填回來,
    # 所以 rec_img的每個pixel 只有一個相應的 move_map pixel,
    # 代表rec_img的每個pixel只會有一個來源,不會同時有 兩個來源,
    # 所以不會有一個合法一個不合法,然後不合法蓋過原本合法值的問題!

    rec_img[over_bound_msk == 1] = 0  ### predict出的move_map超出邊界的pixel設0
    # rec_img[ proc_move_map[...,0]<0 ] = 0
    # rec_img[ proc_move_map[...,0]>dis_col ] = 0
    # rec_img[ proc_move_map[...,1]<0 ] = 0
    # rec_img[ proc_move_map[...,1]>dis_row ] = 0

    # print("cost time:",time.time()-start_time)
    return rec_img
Beispiel #5
0
    def build_page_move_y(row, col, top_curl=27, down_curl=19):
        width = col
        height = row
        x, y = get_xy_map(row, col)

        ### 公式推倒過程看筆記
        A = (-down_curl - top_curl) / (height * (width / 2)**2)
        m = A * (x - (width / 2))**2
        B = (top_curl - 0) * 4 / (
            width**2
        )  ### 原本27-6,但覺得-0也可以,覺得原本-6應該是因為 拍照的誤差造成的 最小移動量要往上跑6,所以不要應該也是可以
        b = B * (
            (x - (width / 2))**2
        ) + 0  ### 原本  +6,但覺得+0也可以,覺得原本+6應該是因為 拍照的誤差造成的 最小移動量要往上跑6,所以不要應該也是可以
        z = m * y + b
        return z
Beispiel #6
0
def apply_move_to_rec2(dis_img, move_map, max_db_move_x, max_db_move_y):

    dis_row, dis_col = dis_img.shape[:2]  ### 原始的 5xx, 5xx,不是5125, 512喔!
    row, col = move_map.shape[:2]  ### 256, 256

    rec_img = np.zeros(shape=(row, col, 3),
                       dtype=np.uint8)  ### 建立存恢復影像的畫布,256,256
    go_x, go_y = get_xy_map(row, col)
    move_map2 = move_map.copy()
    move_map2[..., 0] += go_x + max_db_move_x
    move_map2[..., 1] += go_y + max_db_move_y
    move_map2 = move_map2.astype(np.int32)

    ### 比較最核心的這一步,不用numba 花多少時間:
    ###   不用numba:10000 花8秒
    start_time = time.time()
    for i in range(10000):
        rec_img = dis_img[move_map2[..., 1], move_map2[..., 0], :]
    print("cost time:", time.time() - start_time)

    ###   用numba:10000 花79秒
    start_time = time.time()
    W = col
    H = row
    threadsperblock = (32, 32)
    blockspergrid_x = math.ceil(W / threadsperblock[0])
    blockspergrid_y = math.ceil(H / threadsperblock[1])
    blockspergrid = (blockspergrid_x, blockspergrid_y)
    for i in range(10000):
        kong[blockspergrid,
             threadsperblock](dis_img.astype(np.int32), move_map2,
                              rec_img.astype(np.int32))
    print("cost time:", time.time() - start_time)

    ### 如果 move_map 本身的值已經爆掉了,那rec_img的該點就填0~ 這樣做沒問題!注意我現在是用 move_map 回去 dis_img找顏色填回來,
    # 所以 rec_img的每個pixel 只有一個相應的 move_map pixel,
    # 代表rec_img的每個pixel只會有一個來源,不會同時有 兩個來源,
    # 所以不會有一個合法一個不合法,然後不合法蓋過原本合法值的問題!
    # rec_img[ move_map2[...,0]<0 ] = 0
    # rec_img[ move_map2[...,0]>dis_col ] = 0
    # rec_img[ move_map2[...,1]<0 ] = 0
    # rec_img[ move_map2[...,1]>dis_row ] = 0

    return rec_img
Beispiel #7
0
def build_perspective_move_y(row, col):
    width = col
    height = row
    x, y = get_xy_map(row, col)

    # 寫出係數矩陣 A
    A = np.array([[25**4, 25**3, 25**2, 25**1], [50**4, 50**3, 50**2, 50**1],
                  [100**4, 100**3, 100**2, 100**1],
                  [360**4, 360**3, 360**2, 360**1]])
    # 寫出常數矩陣 B
    B = np.array([-8, 0, 13, -30]).reshape(4, 1)
    # 找出係數矩陣的反矩陣 A_inv
    A_inv = np.linalg.inv(A)
    # 將 A_inv 與 B 相乘,即可得到解答
    ans = A_inv.dot(B)
    print("ans", ans)

    ### 公式推倒過程看筆記
    a = ans[0]  #-0.0000604
    b = ans[1]  #0.2336
    c = ans[2]  #-0.864
    d = ans[3]
    z = a * y**4 + b * y**3 + c * y**2 + d * y**1
    return z
Beispiel #8
0
                        valinit=1,
                        valstep=0.01)
ratio_row_sl = Slider(ratio_row_ax, 'ratio_row', 0, 1, valinit=1, valstep=0.01)
ratio_col_d_sl = Slider(ratio_col_d_ax,
                        'ratio_col_d',
                        0,
                        1,
                        valinit=1,
                        valstep=0.01)
top_curl_sl = Slider(top_curl_ax, 'top_curl', 0, 100, valinit=0, valstep=1)
down_curl_sl = Slider(down_curl_ax, 'down_curl', 0, 100, valinit=0, valstep=1)
lr_shift_sl = Slider(lr_shift_ax, 'lr_shift', 0, 100, valinit=0, valstep=1)

### 3.Slide功能
### 初始化 一些 等等要用到的東西
x, y = get_xy_map(int(row), int(col))  ### 從 0~row 或 0~col
xy_map = np.dstack((x, y))
ax_img = ax.scatter(x, y)
ax = ax.invert_yaxis()

# ax_img = ax.scatter(xy_map[:,0], xy_map[:,1], c = np.arange(row*col), cmap="brg") ### 有漸層顏色,但是很慢所以註解掉了


### 定義 滑動bar時要做的事情
def apply_move():
    global row, col, top_curl, down_curl, lr_shift, ratio_col_t, ratio_row, ratio_col_d, dis_type
    ratio_col_t = ratio_col_t_sl.val
    ratio_row = ratio_row_sl.val
    ratio_col_d = ratio_col_d_sl.val
    top_curl = top_curl_sl.val
    down_curl = down_curl_sl.val