找到第一个红色像素并裁剪图片
Find first red pixel and crop picture
我想用 OpenCV 找到第一个红色像素,然后剪掉右边的其余图片。
此刻我写了这段代码,但它运行起来很慢:
int firstRedPixel = mat.Cols();
int len = 0;
for (int x = 0; x < mat.Rows(); x++)
{
for (int y = 0; y < mat.Cols(); y++)
{
double[] rgb = mat.Get(x, y);
double r = rgb[0];
double g = rgb[1];
double b = rgb[2];
if ((r > 175) && (r > 2 * g) && (r > 2 * b))
{
if (len == 3)
{
firstRedPixel = y - len;
break;
}
len++;
}
else
{
len = 0;
}
}
}
有什么解决办法吗?
这不是处理计算机视觉的方法。我知道这个,因为我也是这样做的。
实现您的目标的一种方法是使用模板匹配与您从图像中剪下的红色条,从而找到红色边框并将其剪掉。
另一种方法是转成HSV space,过滤掉红色内容,根据需要使用等高线查找定位大红色结构。
有很多方法可以做到这一点。尽管在像素值上循环自己很少是正确的方法,并且您不会以这种方式利用复杂的矢量化或算法。
您可以:
1) 找到红色像素(见)
2) 获取红色像素的边界框
3) 裁剪图片
代码是用 C++ 编写的,但它只是 OpenCV 函数,所以移植到 Java:
应该不难
#include <opencv2\opencv.hpp>
int main()
{
cv::Mat3b img = cv::imread("path/to/img");
// Find red pixels
//
cv::Mat3b bgr_inv = ~img;
cv::Mat3b hsv_inv;
cv::cvtColor(bgr_inv, hsv_inv, cv::COLOR_BGR2HSV);
cv::Mat1b red_mask;
inRange(hsv_inv, cv::Scalar(90 - 10, 70, 50), cv::Scalar(90 + 10, 255, 255), red_mask); // Cyan is 90
// Get the rect
std::vector<cv::Point> red_points;
cv::findNonZero(red_mask, red_points);
cv::Rect red_area = cv::boundingRect(red_points);
// Show green rectangle on red area
cv::Mat3b out = img.clone();
cv::rectangle(out, red_area, cv::Scalar(0, 255, 0));
// Define the non red area
cv::Rect not_red_area;
not_red_area.x = 0;
not_red_area.y = 0;
not_red_area.width = red_area.x - 1;
not_red_area.height = img.rows;
// Crop away red area
cv::Mat3b result = img(not_red_area);
return 0;
}
我想用 OpenCV 找到第一个红色像素,然后剪掉右边的其余图片。
此刻我写了这段代码,但它运行起来很慢:
int firstRedPixel = mat.Cols();
int len = 0;
for (int x = 0; x < mat.Rows(); x++)
{
for (int y = 0; y < mat.Cols(); y++)
{
double[] rgb = mat.Get(x, y);
double r = rgb[0];
double g = rgb[1];
double b = rgb[2];
if ((r > 175) && (r > 2 * g) && (r > 2 * b))
{
if (len == 3)
{
firstRedPixel = y - len;
break;
}
len++;
}
else
{
len = 0;
}
}
}
有什么解决办法吗?
这不是处理计算机视觉的方法。我知道这个,因为我也是这样做的。
实现您的目标的一种方法是使用模板匹配与您从图像中剪下的红色条,从而找到红色边框并将其剪掉。
另一种方法是转成HSV space,过滤掉红色内容,根据需要使用等高线查找定位大红色结构。
有很多方法可以做到这一点。尽管在像素值上循环自己很少是正确的方法,并且您不会以这种方式利用复杂的矢量化或算法。
您可以:
1) 找到红色像素(见
2) 获取红色像素的边界框
3) 裁剪图片
代码是用 C++ 编写的,但它只是 OpenCV 函数,所以移植到 Java:
应该不难#include <opencv2\opencv.hpp>
int main()
{
cv::Mat3b img = cv::imread("path/to/img");
// Find red pixels
//
cv::Mat3b bgr_inv = ~img;
cv::Mat3b hsv_inv;
cv::cvtColor(bgr_inv, hsv_inv, cv::COLOR_BGR2HSV);
cv::Mat1b red_mask;
inRange(hsv_inv, cv::Scalar(90 - 10, 70, 50), cv::Scalar(90 + 10, 255, 255), red_mask); // Cyan is 90
// Get the rect
std::vector<cv::Point> red_points;
cv::findNonZero(red_mask, red_points);
cv::Rect red_area = cv::boundingRect(red_points);
// Show green rectangle on red area
cv::Mat3b out = img.clone();
cv::rectangle(out, red_area, cv::Scalar(0, 255, 0));
// Define the non red area
cv::Rect not_red_area;
not_red_area.x = 0;
not_red_area.y = 0;
not_red_area.width = red_area.x - 1;
not_red_area.height = img.rows;
// Crop away red area
cv::Mat3b result = img(not_red_area);
return 0;
}