0%

高通滤波: 通常使用来检测边缘

常见算子

sobel算子

math-1

Scharr算子 (更敏感/细致)

math-2

Laplacian(拉普拉斯)算子 (对噪声较敏感,一般搭配其他操作)

math-3

具体代码例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

import cv2
import numpy as np

%matplotlib inline

# Read in the image
image = cv2.imread('images/curved_lane.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

f, (p1, p2) = plt.subplots(1, 2, figsize=(20,10))
p1.set_title('original img')
p1.imshow(image)

p2.set_title('gray img')
p2.imshow(gray, cmap='gray')
阅读全文 »

低通滤波: 通常使用来去噪

常见滤波类型

均值滤波

math-4

高斯滤波 (权重与距离相关)

math-5

中值滤波

顾名思义取中值

具体代码例子

高斯的模糊/去噪效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Read in the image
image = cv2.imread('images/brain_MR.jpg')

# Convert to grayscale for filtering
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Create a Gaussian blurred image
gray_blur = cv2.GaussianBlur(gray, (9, 9), 0)

# use custom kernal
# gaussian = (1/16)*np.array([[1, 2, 1],
# [2, 4, 2],
# [1, 2, 1]])
#
# gray_blur = cv2.filter2D(gray, -1, gaussian)

f, (ax1, ax2) = plt.subplots(1, 2, figsize=(20,10))
ax1.set_title('original gray'),ax1.imshow(gray, cmap='gray')
ax2.set_title('blurred image'),ax2.imshow(gray_blur, cmap='gray')
阅读全文 »

恢复git stash误删的内容

不小心使用 git drop stash 误删了暂存的内容 (或是 git stash pop 后丢失),怎么恢复?

其实drop后并没有真正删除暂存的内容,而是移除了对它的引用,所以通过一些操作是可以找回的。

模拟误删场景

  • git st 查看当前修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes not staged for commit:
    (use "git add/rm <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)

    deleted: calibration/adjust_result.json
    modified: calibration/config.json
    modified: calibration/src/rd_test.cc
    modified: pose_estimation/CMakeLists.txt
    modified: test/CMakeLists.txt
    modified: test/multiple_sensors.json
    modified: test/src/test_multiple_sensors.cc
  • git stash 暂存修改

    1
    2
    Saved working directory and index state WIP on master: 4d74f8a fix spell
    HEAD is now at 4d74f8a fix spell
  • git stash list 查看暂存内容列表

    1
    stash@{0}: WIP on master: 4d74f8a fix spell
  • git stash drop stash@{0} 移除暂存内容

    1
    Dropped refs/stash@{0} (0b45536f1ce7e859a85f1459d6ae34fc6cdc4039)
阅读全文 »

让自己习惯C++

1. 视C++为一个语言联邦

C++是从四个次语言组成的联邦政府,每个次语言都有自己的规则。

  • C:C++的基础
  • Object-Oriented C++:面向对象设计,类/封装/继承/多态/virtual函数等
  • Template C++:范型编程/模版元编程
  • STL:容器/迭代器/算法/函数对象
阅读全文 »

无人驾驶第一课:从 Apollo 起步

udacity课程链接

概览

硬件

  • 线控驾驶车辆:可通过电子控制的基础车辆,而不仅仅用过实体方向盘、油门踏板、刹车踏板来控制。
  • 控制器区域网络 (CAN) : 车辆的内部通信网络。计算机系统通过CAN卡连接汽车内部网络,发送加速、制动和转向信号。
  • 全球定位系统 (GPS) : 通过绕地卫星接收信号,帮助我们确定所处位置信息。
  • 惯性测量装置 (IMU, Inertial Measurement Unit) : 通过跟踪位置、速度、加速度和其他因素,测量车辆的运动和位置。
  • 激光雷达 (LiDAR) : 由一组脉冲激光器组成,可360度扫描车辆周围,这些激光束的反射形成了可用于了解环境的点云。可用于检测障碍物和检测其他车辆的速度,分辨率低,但成本低且不受天气和照明条件影响。
  • 摄像头捕获图像数据,可使用计算机视觉来了解周围环境,例如检测交通灯。
阅读全文 »

OpenCV像素遍历常用的几种方法

以从 organized 的点云提取 RGB 信息为例

动态地址at

基于Mat对象的随机像素访问 API 实现,通过行列索引方式遍历每个像素值。这种方法速度较慢,不太适合用于像素遍历。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void extract_1(const pcl::PointCloud<PointT>::Ptr cloud, cv::Mat &image)
{
auto &cloud_height = cloud->height;
auto &cloud_width = cloud->width;

image = cv::Mat(cv::Size(cloud_width, cloud_height), CV_8UC3);

#pragma omp parallel for
for (size_t row = 0; row < cloud_height; row++)
{
for (size_t col = 0; col < cloud_width; col++)
{
auto index = row * cloud_width + col;
const auto &pt = cloud->points[index];

image.at<cv::Vec3b>(row, col)[0] = pt.b;
image.at<cv::Vec3b>(row, col)[1] = pt.g;
image.at<cv::Vec3b>(row, col)[2] = pt.r;
}
}
}
阅读全文 »

构造函数

类的构造函数是类的一种特殊的成员函数,用于创建类的新对象和初始化自定义类成员。

  • 构造函数具有与类相同的名称,没有返回值,也不返回 void
  • 可以根据需要定义多个重载构造函数,以各种方式自定义初始化。
  • 构造函数可用于为某些成员变量设置初始值。
  • 通常构造函数具有公共可访问性,因此外部代码可以调用其创建类的对象,但也可以将构造函数声明为 protectedprivate
  • 构造函数可以声明为 inline, explicit, friendconstexpr
  • 构造函数可以初始化已声明为 const, volatile 或者const volatile 的对象,该对象在构造完成后变为 const
  • 如果没有自己声明,编译器将为一个类声明 (编译器版本的) 默认构造函数、复制构造函数、复制赋值操作符和析构函数。所有这些函数都是 publicinline 的。
阅读全文 »

push_back()向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素)。

emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

事实上,大多数情况下二者没有区别,只有在少数情况下 emplace_back() 效率更高。主要是 emplace_back() 支持 in-place construction

阅读全文 »