【问题标题】:find specific points on an image查找图像上的特定点
【发布时间】:2019-02-13 02:53:56
【问题描述】:

我正在尝试制作一个程序来解决一个难题。我的尝试适用于我测试的示例拼图。现在我正在尝试为一个真正的谜题制作一个。 这个新拼图的拼图没有正确的形状。

我设法使图像变成黑白,最后变成 1 和 0 的数组,其中 1 表示片,0 表示背景。我想找到一种方法来识别这些碎片的 4 个角、峰和深度的坐标。

我尝试计算 1 附近 0 的数量,以查看边界中的最大曲线。但是形状不够光滑,无法正常工作。

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

有什么建议、参考或想法吗?

【问题讨论】:

  • 尝试使用角点检测算法。例如,哈里斯算法。这是OpenCVscikit-image 的示例。
  • 我会读到它。谢谢
  • @constt 这些不适用于我的情况.. 我认为角落不够锋利
  • 您标记为红色的角似乎足够锐利,可以被 Harris 算法捕获。玩弄它的参数。找到角后,您可以用多边形近似平铺并从初始图像中减去它。这将显示隆起和凹陷的位置。
  • @constt 到时候我会多尝试一点.. 但我尝试的不是这个。有很多拼图,其中一些有弯曲的角落。我也会尝试驼峰和凹陷的想法,让你知道..谢谢

标签: python image opencv


【解决方案1】:

对于 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);

这里的红色圆圈 - 来自哈里斯的角落和绿色 - 最靠近图像角落。没事吧?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多