Failing to detect a single contour of a chess board square

2_screenshot

Reading the 1st image and trying to find chess board squares using open cv but it fails to find the g1 squares. as you can see in the image above the g and the board edge overlaps what can I do to fix it? so the square is detected:
Better explanation can be found here
Here is the minimum reproducible code:

#include <cassert>
#include <string>
#include <opencv2/opencv.hpp>
#include <cstdbool>
#include <vector>
#include <cwchar>
using std::vector;
using namespace cv;
#define ZERO 0
#define MAXVAL 255
static const cv::Size IMG_ANALYSIS_SZ = cv::Size(500, 500);
static const cv::Size STRUCT_KERN_SZ = cv::Size(2, 2);

void show_images(vector<cv::Mat> images) {
    size_t sz = images.size();
    for (size_t count = 0; count < sz; count++) {
        std::string strCnt = std::to_string(count);
        cv::imshow(strCnt, images[count]);
    }
    while (cv::getWindowProperty("0", cv::WND_PROP_VISIBLE) >= 0) {
        int key = cv::waitKey(200);
        if (key == 27) {  // If Esc key is pressed
            break;
        }
    }
    cv::destroyAllWindows();
}

static inline double angle(cv::Point pt1, cv::Point pt2, cv::Point pt0) { // vec A . vec B = |A| |B| cos(theta) 
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}

static inline bool isSquare(double area, double perimeter, vector<cv::Point> contour) {
    double ratio = (16 * area) / (perimeter * perimeter);
    vector<cv::Point> approx;
    approxPolyDP(contour, approx, perimeter*0.02, true);
    if ((ratio > 0.95 && ratio < 1.05) && approx.size() == 4 && isContourConvex(approx)) {
        double maxCos = 0;
        for(size_t i = 2; i < 5; i++) {
            double cos = fabs(angle(approx[i%4], approx[i-2], approx[i-1]));
            if(cos > maxCos) {
                maxCos = cos;
            }
        }
        if(maxCos < 0.3) {  // cos(90) -> 0
            return true;
        }
    }
    return false;
}

int main(void) {
    cv::Mat img = cv::imread("0_screenshot.png");
    cv::Mat edge_img;
    cv::Canny(img, edge_img, 0, 255);
    Mat kernel = getStructuringElement(MORPH_RECT, STRUCT_KERN_SZ);
    dilate(edge_img, edge_img, kernel);
    // I tried the following codes with different configuration and kernels etc.
    //cv::morphologyEx(edge_img, edge_img, cv::MORPH_OPEN, kernel);
    //cv::morphologyEx(edge_img, edge_img, cv::MORPH_CLOSE, kernel);
    //erode(edge_img, edge_img, kernel);
    vector<vector<cv::Point>> contours;
    cv::findContours(edge_img, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
    size_t sz = contours.size();
    vector<vector<cv::Point>> square_contours;
    for (size_t i = 0; i < sz; i++) {
        double area = cv::contourArea(contours[i]);
        double perimeter = cv::arcLength(contours[i], true);
        // why 3200? image size = 500 x 500 and 64 squares on the board
        // (500 x 500) / 64 = 3906.25, So, area of each square little bit less than 3900
        if(isSquare(area, perimeter, contours[i]) && area > 3200 && area < 3910) { 
            square_contours.push_back(contours[i]);
        }    
    }
    printf("%zu", square_contours.size());
    cv::Mat contour_image = cv::Mat::zeros(edge_img.size(), CV_8UC3);
    cv::drawContours(contour_image, square_contours, -1, cv::Scalar(0, 255, 0), 2);
    show_images({ img, contour_image, edge_img });
    return EXIT_SUCCESS;
}

crosspost:

You could start by detecting horizontal and vertical lines, this should be very easy by doing a sum of white pixels along the horizontal/vertical axis and getting the indices where the sum is more than X%. This will give you X and Y coordinates of the lines.
Then you can extract square images with the coordinates of the top left and bottom right lines.