gpt4 book ai didi

java - OpenCV 寻找轮廓的角点

转载 作者:行者123 更新时间:2023-12-02 10:06:25 25 4
gpt4 key购买 nike

我对 OpenCV 完全陌生。为了练习,我决定做一个“数独求解器”。到目前为止我能够做到这一点:

public Mat processImage(final Mat originalImage, final CvCameraViewFrame frame) {
image = originalImage.clone();
image = frame.gray();

/*
We load the image in grayscale mode. We don't want to bother with the colour information,
so just skip it. Next, we create a blank image of the same size. This image will hold
the actual outer box of puzzle.
*/
Mat outerBox = new Mat(image.size(), CV_8UC1);


/*
Blur the image a little. This smooths out the noise a bit and makes extracting the grid
lines easier.
*/
GaussianBlur(image, image, new Size(11, 11), 0);

/*
With the noise smoothed out, we can now threshold the image. The image can have varying
illumination levels, so a good choice for a thresholding algorithm would be an adaptive
threshold. It calculates a threshold level several small windows in the image.
This threshold level is calculated using the mean level in the window. So it keeps things
illumination independent.

It calculates a mean over a 5x5 window and subtracts 2 from the mean.
This is the threshold level for every pixel.
*/
adaptiveThreshold(image, outerBox, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 5, 2);

/*
Since we're interested in the borders, and they are black, we invert the image outerBox.
Then, the borders of the puzzles are white (along with other noise).
*/
bitwise_not(outerBox, outerBox);

/*
This thresholding operation can disconnect certain connected parts (like lines).
So dilating the image once will fill up any small "cracks" that might have crept in.
*/
Mat kernel = new Mat(3,3, outerBox.type()) {
{
put(0,0,0);
put(0,1,1);
put(0,2,0);

put(1,0,1);
put(1,1,1);
put(1,2,1);

put(2,0,0);
put(2,1,1);
put(2,2,0);
}
};
dilate(outerBox, outerBox, kernel);

final List<MatOfPoint> contours = new ArrayList<>();
findContours(outerBox, contours, new Mat(outerBox.size(), outerBox.type()), CV_SHAPE_RECT, CHAIN_APPROX_SIMPLE);

final Integer biggestPolygonIndex = getBiggestPolygonIndex(contours);

if (biggestPolygonIndex != null) {
setGreenFrame(contours, biggestPolygonIndex, originalImage);
return originalImage;
}

return outerBox;
}

最终看起来像这样

sudokuArea

所以绿色区域内的所有东西都是我的谜题。我的问题是如何提取它并对其进行一些数字识别。

所以在我看来,第一个合乎逻辑的步骤是削减这个区域。但我不知道如何才能得到它。那么如何获得绿色轮廓的角点呢?

欢迎任何帮助/提示。

最佳答案

经过一番尝试,我终于解决了

    final List<MatOfPoint> contours = new ArrayList<>();
findContours(outerBox, contours, new Mat(outerBox.size(), outerBox.type()), CV_SHAPE_RECT, CHAIN_APPROX_SIMPLE);

final Integer biggestPolygonIndex = getBiggestPolygonIndex(contours);
if (biggestPolygonIndex != null) {
final MatOfPoint biggest = contours.get(biggestPolygonIndex);
List<Point> corners = getCornersFromPoints(biggest.toList());
System.out.println("corner size " + corners.size());
for (Point corner : corners) {
drawMarker(originalImage, corner, new Scalar(0,191,255), 0, 20, 3);
}

setGreenFrame(contours, biggestPolygonIndex, originalImage);
}

private List<Point> getCornersFromPoints(final List<Point> points) {
double minX = 0;
double minY = 0;
double maxX = 0;
double maxY = 0;


for (Point point : points) {
double x = point.x;
double y = point.y;

if (minX == 0 || x < minX) {
minX = x;
}
if (minY == 0 || y < minY) {
minY = y;
}
if (maxX == 0 || x > maxX) {
maxX = x;
}
if (maxY == 0 || y > maxY) {
maxY = y;
}
}

List<Point> corners = new ArrayList<>(4);
corners.add(new Point(minX, minY));
corners.add(new Point(minX, maxY));
corners.add(new Point(maxX, minY));
corners.add(new Point(maxX, maxY));

return corners;
}

private Integer getBiggestPolygonIndex(final List<MatOfPoint> contours) {
double maxVal = 0;
Integer maxValIdx = null;
for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
double contourArea = contourArea(contours.get(contourIdx));
if (maxVal < contourArea) {
maxVal = contourArea;
maxValIdx = contourIdx;
}
}

return maxValIdx;
}

private void setGreenFrame(final List<MatOfPoint> contours,
final int biggestPolygonIndex,
Mat originalImage) {
drawContours(originalImage, contours, biggestPolygonIndex, new Scalar(124,252,0), 3);
}

关于java - OpenCV 寻找轮廓的角点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55311775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com