gpt4 book ai didi

OpenCV 使用摄像头检测电视屏幕

转载 作者:太空宇宙 更新时间:2023-11-03 22:46:06 25 4
gpt4 key购买 nike

我正在使用 iPhone 摄像头检测电视屏幕。我目前的方法是逐个像素比较后续帧并跟踪累积差异。结果是二值图像,如图所示。

Original image

对我来说这看起来像一个矩形,但 OpenCV 不这么认为。它的侧面不是完全笔直的,有时甚至会有更多的颜色渗出,使检测变得困难。这是我尝试检测矩形的 OpenCV 代码,因为我对 OpenCV 不是很熟悉,所以它是从我找到的一些示例中复制的。

uint32_t *ptr = (uint32_t*)CVPixelBufferGetBaseAddress(buffer);
cv::Mat image((int)width, (int)height, CV_8UC4, ptr); // unsigned 8-bit values for 4 channels (ARGB)

cv::Mat image2 = [self matFromPixelBuffer:buffer];

std::vector<std::vector<cv::Point>>squares;

// blur will enhance edge detection

cv::Mat blurred(image2);
GaussianBlur(image2, blurred, cvSize(3,3), 0);//change from median blur to gaussian for more accuracy of square detection

cv::Mat gray0(blurred.size(), CV_8U), gray;

std::vector<std::vector<cv::Point> > contours;

// find squares in every color plane of the image
for (int c = 0; c < 3; c++) {
int ch[] = {c, 0};
mixChannels(&blurred, 1, &gray0, 1, ch, 1);

// try several threshold levels
const int threshold_level = 2;
for (int l = 0; l < threshold_level; l++) {
// Use Canny instead of zero threshold level!
// Canny helps to catch squares with gradient shading
if (l == 0) {
Canny(gray0, gray, 10, 20, 3); //

// Dilate helps to remove potential holes between edge segments
dilate(gray, gray, cv::Mat(), cv::Point(-1,-1));
} else {
gray = gray0 >= (l+1) * 255 / threshold_level;
}

// Find contours and store them in a list
findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

// Test contours
std::vector<cv::Point> approx;
int biggestSize = 0;
for (size_t i = 0; i < contours.size(); i++) {
// approximate contour with accuracy proportional
// to the contour perimeter
approxPolyDP(cv::Mat(contours[i]), approx, arcLength(cv::Mat(contours[i]), true)*0.02, true);
if (approx.size() != 4)
continue;

// Note: absolute value of an area is used because
// area may be positive or negative - in accordance with the
// contour orientation
int areaSize = fabs(contourArea(cv::Mat(approx)));
if (approx.size() == 4 && areaSize > biggestSize)
biggestSize = areaSize;
cv::RotatedRect boundingRect = cv::minAreaRect(approx);
float aspectRatio = boundingRect.size.width / boundingRect.size.height;

cv::Rect boundingRect2 = cv::boundingRect(approx);
float aspectRatio2 = (float)boundingRect2.width / (float)boundingRect2.height;

bool convex = isContourConvex(cv::Mat(approx));
if (approx.size() == 4 &&
fabs(contourArea(cv::Mat(approx))) > minArea &&
(aspectRatio >= minAspectRatio && aspectRatio <= maxAspectRatio) &&
isContourConvex(cv::Mat(approx))) {
double maxCosine = 0;

for (int j = 2; j < 5; j++) {
double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
maxCosine = MAXIMUM(maxCosine, cosine);
}
double area = fabs(contourArea(cv::Mat(approx)));
if (maxCosine < 0.3) {
squares.push_back(approx);
}
}
}
}

在 Canny-step 之后图像看起来像这样:

Image after Canny-step对我来说似乎很好,但由于某种原因未检测到矩形。谁能解释我的参数是否有问题?

我的第二种方法是使用 OpenCV 霍​​夫线检测,基本上使用与上面相同的代码,对于 Canny 图像,我然后调用 HoughLines 函数。它给了我很多线条,因为我不得不降低阈值来检测垂直线条。结果如下所示:

Hough lines

问题是有很多行。如第一张图片所示,如何找出与蓝色矩形边接触的线?

或者是否有更好的方法来检测屏幕?

最佳答案

首先,找到最大面积轮廓reference , 然后计算最小面积矩形 reference ,将轮廓面积除以矩形面积,如果它足够接近 1,那么你的轮廓类似于矩形。这将是您需要的轮廓和矩形。

关于OpenCV 使用摄像头检测电视屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47175206/

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