

画像の中にある黒いドットを横に連結させたいです。

cv2
のcontoursで輪郭を検出し、ユークリッド距離を用いて、取得した輪郭座標間の間隔が最大になるように四点の座標を作成しました。その後、黒いドット間の白いスペースをcv2.fillPoly
で埋めてみましたが、画像の中心部がうまく処理できません。  
もしよろしければ、ご教授いただけないでしょうか？

画像の生成方法は以下の通りです。

[code]

    from PIL import Image, ImageDraw
    
    # 画像の設定
    width, height = 1000, 1000
    dot_size = 20
    dot_interval = 20
    shift_right = 20
    
    # 画像の生成
    image = Image.new("RGB", (width, height), "white")
    draw = ImageDraw.Draw(image)
    
    # ドットの描写
    for i in range(shift_right, width, dot_size + dot_interval):
        for j in range(0, height, dot_size + dot_interval):
            draw.rectangle([i, j, i + dot_size, j + dot_size], fill="black")
    
    # 画像の保存
    image.save("shifted_square_dot_pattern.png")
    
    
    import cv2
    import numpy as np
    
    # 画像のロード
    image = cv2.imread("shifted_square_dot_pattern.png", cv2.IMREAD_GRAYSCALE)
    rows, cols = image.shape
    
    # マッピング設定
    def gaussian_skew_mapping(x, y, amplitude, sigma):
        return amplitude * np.exp(-((y - rows // 2) ** 2) / (2 * sigma ** 2))
    
    # 変形行列
    transformation_matrix = np.float32([[1, 0, 0], [0, 1, 0]])
    skewed_image = np.zeros_like(image)
    
    for y in range(rows):
        for x in range(cols):
            deformation = int(gaussian_skew_mapping(x, y, 20, 100))
            new_x = x + deformation
            if 0 <= new_x < cols:
                skewed_image[y, new_x] = image[y, x]
    
    # 変形画像の保存
    cv2.imwrite("gaussian_skewed_shifted_square_dot_pattern.png", skewed_image)
    
[/code]

画像の処理は以下の通りです

[code]

    import matplotlib.pyplot as plt
    img_h = cv2.imread("gaussian_skewed_shifted_square_dot_pattern.png")
    gray_h = cv2.cvtColor(img_h, cv2.COLOR_BGR2GRAY)
    # 2値化処理
    # 画像の特徴的な部分、関心のある部分を抽出するように変換する処理
    threshold=130
    ret, gray_h_thresh = cv2.threshold(gray_h,threshold,255,cv2.THRESH_BINARY_INV)
    plt.imshow(gray_h_thresh)
    #輪郭抽出
    contours, hierarchy = cv2.findContours(gray_h_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    #輪郭の個数を表示
    print(len(contours))
    
    #左のドットではないスペースを削除
    count =0
    areas = []
    list_contours = list(contours)
    for i in range(len(contours)):
        area = cv2.contourArea(contours[i], True)
        areas.append(area)
       
        if area < -500:
            print(count)
            del list_contours[i]
        count+=1
    
    #contours のサイズを2 x 4 に成形、ユークリッド距離を用いて近い座標を削除
    for i in range(len(trimed_list_contours)):
        if not trimed_list_contours[i].shape[0] ==4:
            sq_index =[]
            for j in range(trimed_list_contours[i].shape[0]-1):
                euclidean_distance = np.sqrt(sum(sum((trimed_list_contours[i][j]-trimed_list_contours[i][j+1])**2)))
                sq_index.append(euclidean_distance)
        
            for k in range(trimed_list_contours[i].shape[0]-4):
                argmin = np.argmin(sq_index)
                trimed_list_contours[i] =np.delete(trimed_list_contours[i],argmin,0)
                sq_index = np.delete(sq_index,argmin,0)
    
    #平行にドットをつなげる
    count = 0
    copy_gray_h=gray_h.copy()
    #for i in range(0,26):
    for i in range(len(trimed_list_contours)):
        count+=1
        if count == 25:
            count =0
            
            continue
        else:
            
            # Assuming you have a list or tuple of points from OpenCV, for example:
            opencv_points = [trimed_list_contours[i][0][0], trimed_list_contours[i][1][0], trimed_list_contours[i+1][2][0],trimed_list_contours[i+1][3][0]]
    
           
            opencv_points =np.vstack(opencv_points)
            cv2.fillPoly(copy_gray_h, [opencv_points], (0, 0, 0))
            
    plt.imshow(copy_gray_h)
    plt.show()
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/xOMkym.png)](https://i.stack.imgur.com/xOMkym.png)


CC BY-SA 4.0
2023-04-18T13:07:27.590
94563
2023-04-19T14:19:39.293
2023-04-19T14:18:20.987
52968
52968
question
python numpy opencv pillow
画像の中にあるドットを横に連結させたい


**[自己解決]**  
目的の画像をドットのピクセル分だけ下にシフトし、元画像と合成することで疑似的に解決しました。

修正コード

[code]

    import matplotlib.pyplot as plt
    img_h = cv2.imread("gaussian_skewed_shifted_square_dot_pattern.png")
    gray_h = cv2.cvtColor(img_h, cv2.COLOR_BGR2GRAY)
    inv_im_gray_h = cv2.bitwise_not(gray_h)
    
    dot_pixel_size =20
    
    
    # 横方向にドットのピクセルサイズ分だけずらす
    rows, cols, = inv_im_gray_h.shape
    shifted_image = np.zeros_like(inv_im_gray_h)
    shifted_image[:, dot_pixel_size:] = inv_im_gray_h[:, :-dot_pixel_size]
    shifted_image[:,:dot_pixel_size]= 255
    
    #画像の合成
    merged_image = inv_im_gray_h+shifted_image
    plt.imshow(merged_image, cmap = "Greys")
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/1bIOI.png)](https://i.stack.imgur.com/1bIOI.png)


CC BY-SA 4.0
2023-04-19T14:19:39.293
94577
2023-04-19T14:19:39.293
52968
94563
answer