简体   繁体   English

找到图像上的特定点

[英]find specific points on an image

I am trying to make a program to solve a puzzle an. 我正在尝试制作一个解决难题的程序。 My attempts work good with sample puzzles I made to test. 我的尝试与我测试的样本拼图一起工作得很好。 Now I am trying to make one for a actual puzzle. 现在我正在尝试制作一个真正的拼图。 The puzzle pieces of this new puzzle don't really have a proper shape. 这个新拼图的拼图块并没有真正的形状。

拼图块

I managed to make the image into black and white and finally in to array of 1s and 0s where 1s indicate the piece and 0s background. 我设法将图像变成黑白,最后变成1和0的数组,其中1表示片段,0表示背景。 I want to find a way to identify the coordinates of the 4 corners, peaks and depths of these pieces. 我想找到一种方法来识别这些碎片的4个角,峰和深度的坐标。

点

I tried to count the numbers of 0s near the 1s to see the maximum curves in the border. 我试图计算1附近的0的数量,以查看边界中的最大曲线。 But the shapes are not smooth enough for it to work. 但是它的形状不够平滑,无法工作。

counter = np.zeros((lenX,lenY),dtype=int)
for i in range(lenX):
    for j in range(lenY):
        if img[i,j]==1:
            counter[i,j] = count_white(img,i,j,lenX,lenY)

print(counter)
tpath = os.getcwd()+"/test.jpg"
print(cv2.imwrite(tpath, Image))
print("saved at : ",tpath)
np.savetxt("test.csv", counter, delimiter=",")

def count_white(img,x,y,lenX,lenY):
    X = [x-1,x,x+1,x+1,x+1,x,x-1,x-1]
    Y = [y-1,y-1,y-1,y,y+1,y+1,y+1,y]
    count = 0
    for i in range(len(X)):
        if X[i] < lenX and Y[i] < lenY:
            if img[X[i],Y[i]] == 0:
                count=count+1
    return count

Any suggestion, references or ideas? 有任何建议,参考或想法吗?

Sorry for the C++ code but it works for your case: 对不起C ++代码,但它适用于您的情况:

cv::Mat gray = cv::imread("Sq01a.png", cv::IMREAD_GRAYSCALE);

gray = 255 - gray;


cv::Mat bin;
cv::threshold(gray, bin, 1, 255, cv::THRESH_BINARY);

cv::Mat bigBin(2 * bin.rows, 2 * bin.cols, CV_8UC1, cv::Scalar(0));
bin.copyTo(cv::Mat(bigBin, cv::Rect(bin.cols / 2, bin.rows / 2, bin.cols, bin.rows)));


std::vector<std::vector<cv::Point> > contours;
cv::findContours(bigBin, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

if (contours.size() > 0)
{
    std::vector<cv::Point> tmp = contours[0];
    const cv::Point* elementPoints[1] = { &tmp[0] };
    int numberOfPoints = (int)tmp.size();
    cv::fillPoly(bigBin, elementPoints, &numberOfPoints, 1, cv::Scalar(255, 255, 255), 8);
}

int maxCorners = 20;
double qualityLevel = 0.01;
double minDistance = bigBin.cols / 8;
int blockSize = 5;
bool useHarrisDetector = true;
double k = 0.04;
std::vector<cv::Point2f> corners;
cv::goodFeaturesToTrack(bigBin, corners, maxCorners, qualityLevel, minDistance, cv::noArray(), blockSize, useHarrisDetector, k);

std::vector<cv::Point2f> resCorners;
std::vector<cv::Point2f> imgCorners = { cv::Point2f(0, 0), cv::Point2f(bigBin.cols, 0), cv::Point2f(bigBin.cols, bigBin.rows), cv::Point2f(0, bigBin.rows) };
for (auto imgCorn : imgCorners)
{
    size_t best_i = corners.size();
    float min_dist = bigBin.cols * bigBin.rows;
    for (size_t i = 0; i < corners.size(); ++i)
    {
        float dist = cv::norm(imgCorn - corners[i]);
        if (dist < min_dist)
        {
            best_i = i;
            min_dist = dist;
        }
    }
    if (best_i != corners.size())
    {
        resCorners.push_back(corners[best_i]);
    }
}
cv::Mat bigColor;
cv::cvtColor(bigBin, bigColor, cv::COLOR_GRAY2BGR);
for (auto corner : corners)
{
    cv::circle(bigColor, corner, 10, cv::Scalar(0, 0, 255.), 1);
}
for (auto corner : resCorners)
{
    cv::circle(bigColor, corner, 5, cv::Scalar(0, 255, 0), 2);
}

cv::imshow("gray", gray);
cv::imshow("bigColor", bigColor);
cv::waitKey(0);

Here red circles - corners from Harris and green - the nearest to the image corners. 这里有红色圆圈 - 来自哈里斯和绿色的角落 - 最接近图像的角落。 It's OK? 没关系?

结果:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM