- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我编写了一个简短的程序来演示使用 OpenCV 进行霍夫线检测。
在最后一步,代码采用原始的模糊灰度图像,叠加 Canny 边缘检测结果,然后叠加霍夫变换检测到的线。
hough 线被渲染为纯红色 (R=255),3px 线,但是当我覆盖它们时,由于某种原因下图显示出来。示例如下。
原始图片:
带有 Canny 边缘 + 霍夫线覆盖的模糊灰度图像:
放大片段:
可以看出,灰度图像穿过(明显)纯红色。这是为什么?
完整代码如下:
houghtest.cpp
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "toolbarconfig.h"
using namespace cv;
// Global variables
const char* window_name = "Hough Line Detection";
ToolbarConfig
gaussian = ToolbarConfig(0, 15, 1, 6),
canny = ToolbarConfig(20, 150, 2, 40),
hough = ToolbarConfig(50, 400, 10, 200);
Mat input;
// Function prototypes
void update(int, void*);
void chromakey(const Mat under, const Mat over, Mat *dst, const Scalar& color);
void help();
/**
* Creates an interactive example of running hough line detection on a
* sample image
*/
int main( int argc, char** argv ) {
const char* filename = argc >= 2 ? argv[1] : "pic1.png";
input = imread(filename, CV_LOAD_IMAGE_COLOR); if(input.empty()) {
help();
std::cout << "Can not open " << filename << std::endl;
return -1;
}
// Convert the image to grayscale
cvtColor(input, input, CV_BGR2GRAY);
// Create a window
namedWindow(window_name, CV_WINDOW_AUTOSIZE);
// Create trackbars for the user to enter thresholds
createTrackbar("Gaussian Kernel Size", window_name, &(gaussian.t_current), gaussian.tmax(), update);
createTrackbar("Canny Min Threshold", window_name, &(canny.t_current), canny.tmax(), update);
createTrackbar("Hough Line Threshold", window_name, &(hough.t_current), hough.tmax(), update);
// Show the image
update(NULL, NULL);
// Wait until user exit program by pressing a key
waitKey(0);
return 0;
}
/**
* Trackbar callback - updates the display
*/
void update(int, void*) {
const int CANNY_RATIO = 3, CANNY_KERNEL_SIZE = 3;
Mat blurred_input, canny_edges, hough_lines;
// Reduce noise with a gaussian kernel
if(gaussian.current() != 0) {
blur(input, blurred_input, Size(gaussian.current(), gaussian.current()));
} else {
blurred_input = input;
}
// Run Canny edge detector
Canny(blurred_input, canny_edges, canny.current(), canny.current()*CANNY_RATIO, CANNY_KERNEL_SIZE);
// ==== Begin Hough line detector phase
// Create a vector to store the located lines in
vector<Vec2f> line_vector;
// Run the transform
HoughLines(canny_edges, line_vector, 1, CV_PI/180, hough.current(), 0, 0);
//std::cout << lines.size() << " lines detected" << std::endl;
// Prepare the hough_lines image
hough_lines = Mat::zeros(canny_edges.rows, canny_edges.cols, CV_8UC3);
// Draw detected lines into an image
for(size_t i = 0; i < line_vector.size(); i++) {
float rho = line_vector[i][0], theta = line_vector[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
line(hough_lines, pt1, pt2, Scalar(0, 0, 255), 3, 0);
}
// Overlay the hough lines onto the original blurred image
Mat blurred_input_color, canny_edges_color, input_with_canny, combined_images;
cvtColor(blurred_input, blurred_input_color, CV_GRAY2BGR);
cvtColor(canny_edges, canny_edges_color, CV_GRAY2BGR);
chromakey(blurred_input_color, canny_edges_color, &input_with_canny, Scalar(0, 0, 0));
chromakey(input_with_canny, hough_lines, &combined_images, Scalar(0, 0, 0));
// Display the result
imshow(window_name, combined_images);
}
/**
* Takes two images and overlays them, using color as a chroma-key
* Any pixels in the 'over' image that match the given color value will
* effectively be transparent - the 'under' image will show through
*
* @precondition: All passed images must first be in BGR format
*/
void chromakey(const Mat under, const Mat over, Mat *dst, const Scalar& color) {
// Mats must be the same size
if(under.rows != over.rows || under.cols != over.cols) {
std::cout << "Error, image dimensions must match" << std::endl;
return;
}
// Create the destination matrix
*dst = Mat::zeros(under.rows, under.cols, CV_8UC3);
for(int y=0; y<under.rows; y++) {
for(int x=0; x<under.cols; x++) {
dst->at<Vec3b>(y,x)[0] = over.at<Vec3b>(y,x)[0] == color[0] ? under.at<Vec3b>(y,x)[0] : over.at<Vec3b>(y,x)[0];
dst->at<Vec3b>(y,x)[1] = over.at<Vec3b>(y,x)[1] == color[1] ? under.at<Vec3b>(y,x)[1] : over.at<Vec3b>(y,x)[1];
dst->at<Vec3b>(y,x)[2] = over.at<Vec3b>(y,x)[2] == color[2] ? under.at<Vec3b>(y,x)[2] : over.at<Vec3b>(y,x)[2];
}
}
}
/**
* Prints usage information
*/
void help() {
std::cout << "\nThis program demonstrates line finding with the Hough transform.\n" "Usage:\n"
"./houghlines <image_name>, Default is pic1.png\n" << std::endl;
}
工具栏配置.h
#ifndef TOOLBARCONFIG_H
#define TOOLBARCONFIG_H
class ToolbarConfig {
public:
ToolbarConfig(int min, int max, int stepsize, int current);
int w2t(int world_value);
int t2w(int toolbar_value);
int current();
int tmax();
int tmin();
int min;
int max;
int stepsize;
int t_current;
};
#endif
工具栏配置.cpp
#include <algorithm>
#include "toolbarconfig.h"
ToolbarConfig::ToolbarConfig(int min, int max, int stepsize, int current) {
this->min = min;
this->max = max;
this->stepsize = stepsize;
this->t_current = this->w2t(current);
}
int ToolbarConfig::w2t(int world_value) {
return int((std::min(std::max(world_value, min), max) - min) / stepsize);
}
int ToolbarConfig::t2w(int toolbar_value) {
return toolbar_value * stepsize + min;
}
int ToolbarConfig::current() {
return t2w(t_current);
}
int ToolbarConfig::tmax() {
return w2t(max);
}
int ToolbarConfig::tmin() {
return w2t(min);
}
如果需要,我很乐意提供我的 Makefile。
提前致谢。
最佳答案
错误一定是在这里:
dst->at<Vec3b>(y,x)[0] = over.at<Vec3b>(y,x)[0] == color[0] ? under.at<Vec3b>(y,x)[0] : over.at<Vec3b>(y,x)[0];
dst->at<Vec3b>(y,x)[1] = over.at<Vec3b>(y,x)[1] == color[1] ? under.at<Vec3b>(y,x)[1] : over.at<Vec3b>(y,x)[1];
dst->at<Vec3b>(y,x)[2] = over.at<Vec3b>(y,x)[2] == color[2] ? under.at<Vec3b>(y,x)[2] : over.at<Vec3b>(y,x)[2];
当你第一次打电话时
chromakey(blurred_input_color, canny_edges_color, &input_with_canny, Scalar(0, 0, 0));
canny_edges_color
的白色像素值为 (255, 255, 255),所以在上面的比较中,你会得到 over
每个 channel 的值,因此像素的颜色将为 (255, 255, 255),图像将正确显示。
然而,在第二种情况下:
chromakey(input_with_canny, hough_lines, &combined_images, Scalar(0, 0, 0));
你的hugh_lines
红色像素的值为 (0, 0, 255),因此对于前两次比较,它们将获得值 under
。 , 因为
over.at<Vec3b>(y,x)[0] == color[0]
和
over.at<Vec3b>(y,x)[1] == color[1]
.
只有 dst->at<Vec3b>(y,x)[2]
将获得 255 值。为了使线条显示为实线,它应该是 dst->at<Vec3b>(y,x)[0] = 0
和 dst->at<Vec3b>(y,x)[1] = 0
而不是在这种情况下。
此外,根据 this answer你应该像这样初始化 *dst:
*dst = Mat(under.rows,under.cols,CV_8UC3,CV_RGB(0,0,0));
因为它是一个 3 channel 垫。
关于c++ - OpenCV 不需要的颜色混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12454134/
我正在尝试从我的系统中完全删除 opencv。我试图学习 ROS,而在教程中我遇到了一个问题。创建空工作区后,我调用catkin_make 它给出了一个常见错误,我在 answers.ros 中搜索并
我在尝试逐步转移对warpAffine的调用时遇到崩溃(不是异常): void rotateImage( const Mat& source, double degree, Mat& output )
如何处理opencv gpu异常?是否有用于opencvgpu异常处理的特定错误代码集api? 我尝试了很多搜索,但只有1个错误代码,即CV_GpuNotSupported。 请帮帮我。 最佳答案 虽
笔记 我是 OpenCV(或计算机视觉)的新手,所以告诉我搜索查询会很有帮助! 我想问什么 我想编写一个从图片中提取名片的程序。 我能够提取粗略的轮廓,但反射光会变成噪点,我无法提取准确的轮廓。请告诉
我想根据像素的某个阈值将Mono16类型的Mat转换为二进制图像。我尝试使用以下内容: 阈值(img,ret,0.1,1,CV_THRESH_BINARY); 尝试编译时,出现make错误,提示: 错
我对使用GPU加速的OpenCV中的卷积函数有疑问。 使用GPU的卷积速度大约快3.5 运行时: convolve(src_32F, kernel, cresult, false, cbuffer);
我正在尝试使用非对称圆圈网格执行相机校准。 我通常找不到适合CirclesGridFinder的文档,尤其是findHoles()函数的文档。 如果您有关于此功能如何工作以及其参数含义的信息,将不胜感
在计算机上绘图和在 OpenCV 的投影仪上投影之间有什么区别吗? 一种选择是投影显示所有内容的计算机屏幕。但也许也有这样的选择,即在投影仪上精确地绘制和投影图像,仅使用计算机作为计算机器。如果我能做
我将Processing(processing.org)用于需要人脸跟踪的项目。现在的问题是由于for循环,程序将耗尽内存。我想停止循环或至少解决内存不足的问题。这是代码。 import hyperm
我有下面的代码: // Image Processing.cpp : Defines the entry point for the console application. // //Save
我正在为某些项目使用opencv。并有应解决的任务。 任务很简单。我有一张主图片,并且有一个模板,而不是将主图片与模板进行比较。我使用matchTemplate()函数。我只是好奇一下。 在文档中,我
我正在尝试使用以下命令创建级联分类器: haartraining -data haarcascade -vec samples.vec -bg negatives.dat -nstages 20 -n
我试图使用OpenCV检测黑色图像中一组形状的颜色,为此我使用了Canny检测。但是,颜色输出总是返回为黑色。 std::vector > Asteroids::DetectPoints(const
我正在尝试使用OpenCv 2.4.5从边缘查找渐变方向,但是我在使用cvSobel()时遇到问题,以下是错误消息和我的代码。我在某处读到它可能是由于浮点(??)之间的转换,但我不知道如何解决它。有帮
我正在尝试构建循环关闭算法,但是在开始开发之前,我想测试哪种功能描述符在真实数据集上效果更好。 我有两个在两个方向拍摄的走廊图像,一个进入房间,另一个离开同一个房间。因此它们代表相同的场景,但具有2个
有没有一种方法可以比较直方图,但例如要排除白色,因此白色不会影响比较。 最佳答案 白色像素有 饱和度 , S = 0 .因此,在创建直方图时很容易从计数中删除白色像素。请执行下列操作: 从 BGR 转
就像本主题的标题一样,如何在OpenCV中确定图像的特定像素(灰度或彩色)是否饱和(例如,亮度过高)? 先感谢您。 最佳答案 根据定义,饱和像素是指与强度(即灰度值或颜色分量之一)等于255相关联的像
我是OpenCV的新用户,正在从事大学项目。程序会获取输入图像,对其进行综合模糊处理,然后对其进行模糊处理。当对合成模糊图像进行反卷积时,会生成边界伪像,因为...好吧,到目前为止,我还没有实现边界条
我想知道OpenCV是haar特征还是lbp是在多尺度搜索过程中缩放图像还是像论文中提到的那样缩放特征本身? 编辑:事实证明,检测器可以缩放图像,而不是功能。有人知道为什么吗?通过缩放功能可以更快。
我在openCv中使用SVM.train命令(已定义了适当的参数)。接下来,我要使用我的算法进行分类,而不是使用svm.predict。 可能吗?我可以访问训练时生成的支持 vector 吗?如果是这
我是一名优秀的程序员,十分优秀!