def raw_reg(fixed_img, float_img, init_offset, down_rate, lv, method="FFT"):
    if type(fixed_img) == Image.Image:
        Img_fix = sp.misc.fromimage(
            fixed_img, True
        )  # flatten is True, means we convert images into graylevel images.
        Img_float = sp.misc.fromimage(float_img, True)
    else:
        Img_fix = fixed_img
        Img_float = float_img
    if method == "FFT":
        con_s = dict(angle=[0, 0], scale=[1, 1])
        sim = ird.similarity(Img_fix, Img_float, constraints=con_s)
        tvec = sim["tvec"].round(4)
        score = sim["success"]
        offset = [tvec[1], tvec[0]]
    elif method == "ECC":
        warp_mode = cv2.MOTION_TRANSLATION
        warp_matrix = np.eye(2, 3, dtype=np.float32)
        number_of_iterations = 500  # Specify the number of iterations.
        termination_eps = 1e-8  # in the correlation coefficient between two iterations
        criteria = (cv2.TERM_CRITERIA_COUNT | cv2.TERM_CRITERIA_EPS,
                    number_of_iterations, termination_eps
                    )  # Define termination criteria
        try:
            (score,
             warp_matrix) = cv2.findTransformECC(Img_fix, Img_float,
                                                 warp_matrix, warp_mode,
                                                 criteria)
            offset = [warp_matrix[0, 2], warp_matrix[1, 2]]
        except:
            logging.warning("Unaligned patch")
            offset = [0, 0]
            score = 0
    elif method == "SIFT":
        stitcher = Stitcher()
        Img_fix = np.array(fixed_img)
        Img_float = np.array(float_img)
        matches, ptsA, ptsB, H, status = stitcher.returnMatchCoord([
            Img_fix, Img_float
        ])  # here, already with RANSAC algorithm to match key points
        matched_ptsA = []
        matched_ptsB = []
        slops = []
        offsets = []
        for m_idx, m in enumerate(ptsA):
            if status[m_idx] == 1:
                matched_ptsA.append(m)
                matched_ptsB.append(ptsB[m_idx])
                if (ptsB[m_idx][0] - m[0]) == 0:
                    s = 999999
                else:
                    s = (ptsB[m_idx][1] - m[1]) / (ptsB[m_idx][0] - m[0])
                offsetY = ptsB[m_idx][1] - m[1]
                offsetX = ptsB[m_idx][0] - m[0]
                slops.append(s)
                offsets.append([offsetX, offsetY])
        offset = np.mean(offsets, 0)  # use mean offset as offset
        score = np.mean(np.std(offsets, 0))  # use std as score
    elif method == "SIFT_ENH":
        stitcher = Stitcher()
        Img_fix = np.array(fixed_img)
        Img_float = np.array(float_img)
        matches, ptsA, ptsB, H, status = stitcher.returnMatchCoord([
            Img_fix, Img_float
        ])  # here, already with RANSAC algorithm to match key points
        matched_ptsA = []
        matched_ptsB = []
        slops = []
        offsets = []
        for m_idx, m in enumerate(ptsA):
            if status[m_idx] == 1:
                matched_ptsA.append(m)
                matched_ptsB.append(ptsB[m_idx])
                if (ptsB[m_idx][0] - m[0]) == 0:
                    s = 999999
                else:
                    s = (ptsB[m_idx][1] - m[1]) / (ptsB[m_idx][0] - m[0])
                offsetY = ptsB[m_idx][1] - m[1]
                offsetX = ptsB[m_idx][0] - m[0]
                slops.append(s)
                offsets.append([offsetX, offsetY])
        # use a complicate way to distill matched key points
        if len(slops) > 0:
            max_slop = np.amax(slops)
            min_slop = np.amin(slops)
            bins = int(len(slops) / 2)
            slop_hist = histogram(slops, min_slop, max_slop, bins)
            step = (max_slop - min_slop) / bins
            idx_max_count = slop_hist.index(max(slop_hist))
            if type(idx_max_count) == list:
                idx_max_count = idx_max_count[0]
            low_range = min_slop + idx_max_count * step
            high_range = min_slop + (idx_max_count + 1) * step
            idx_s_list = []
            for idx_s, s in enumerate(slops):
                if low_range <= s <= high_range:
                    idx_s_list.append(idx_s)
            offset = np.mean([offsets[i] for i in idx_s_list], 0)
            score = 1 / (np.mean(np.std([offsets[i] for i in idx_s_list], 0)) +
                         0.00000001)
        else:
            logging.warning("Unable to match this patch")
            return [0, 0], 0
    else:
        return [0, 0], 0
    offset = [
        offset[0] + init_offset[0] / down_rate[lv],
        offset[1] + init_offset[1] / down_rate[lv]
    ]
    return offset, score
                Img_fix_col
            )  # flatten is True, means we convert images into graylevel images.
            Img_float = np.array(Img_float_col)
            stitcher = Stitcher()

            # (result, vis) = stitcher.stitch([Img_fix, Img_float], showMatches=True)
            # cv2.imwrite("ImageA.jpg", cv2.cvtColor(Img_fix, cv2.COLOR_BGR2RGB))
            # cv2.imwrite("ImageB.jpg", cv2.cvtColor(Img_float, cv2.COLOR_BGR2RGB))
            # cv2.imwrite("matches.jpg", cv2.cvtColor(vis, cv2.COLOR_BGR2RGB))
            # cv2.imwrite("Result.jpg", cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
            # print("OK")
            '''
            if the rotation angle is confirmed to be 0, we can use below method to distill offset.
            '''
            matches, ptsA, ptsB, H, status = stitcher.returnMatchCoord([
                Img_fix, Img_float
            ])  # here, already with RANSAC algorithm to match key points
            matched_ptsA = []
            matched_ptsB = []
            slops = []
            offsets = []
            for m_idx, m in enumerate(ptsA):
                if status[m_idx] == 1:
                    matched_ptsA.append(m)
                    matched_ptsB.append(ptsB[m_idx])
                    s = (ptsB[m_idx][1] - m[1]) / (ptsB[m_idx][0] - m[0])
                    offsetY = ptsB[m_idx][1] - m[1]
                    offsetX = ptsB[m_idx][0] - m[0]
                    slops.append(s)
                    offsets.append([offsetX, offsetY])
            # # an alternative way is just use the mean