OpenCV-3.4.3图像通道处理

  • 图像通道处理

图像读取和处理都是按BGR通道顺序进行的

 1 #include <iostream>
 2 #include <opencv2/opencv.hpp>
 3 #include "opencv2/highgui/highgui.hpp"
 4 #include "opencv2/imgproc/imgproc.hpp"
 5 
 6 int main(int argc, char **argv) {
 7     cv::Mat src = cv::imread("/home/cv/Downloads/images/P1180141.JPG", 1);
 8     cv::resize(src, src, cv::Size(src.cols / 3, src.rows / 3), cv::INTER_CUBIC);
 9     cv::imshow("original_after_resize", src);
10     
11     // blue channel
12     cv::Mat mytemp1(src.rows, src.cols, CV_8UC3, cv::Scalar(255, 0, 0));
13     cv::imshow("temp test", mytemp1);
14     // green channel
15     cv::Mat mytemp2(src.rows, src.cols, CV_8UC3, cv::Scalar(0, 255, 0));
16     cv::imshow("temp test", mytemp2);
17     // red channel
18     cv::Mat mytemp3(src.rows, src.cols, CV_8UC3, cv::Scalar(0, 0, 255));
19     cv::imshow("temp test", mytemp3);
20     cv::waitKey(0);
21     return 0;
22 }

或者使用mixChannels函数

 1 #include <opencv2/opencv.hpp>
 2 #include "opencv2/highgui/highgui.hpp"
 3 #include "opencv2/imgproc/imgproc.hpp"
 4 
 5 int main(int argc, char **argv) {
 6     cv::Mat src = cv::imread("/home/cv/Downloads/images/P1180141.JPG", 1);
 7     cv::resize(src, src, cv::Size(src.cols / 3, src.rows / 3), cv::INTER_CUBIC);
 8     for (int i = 0; i < 3; i++) {
 9         cv::Mat temp_bgr(src.rows, src.cols, CV_8UC3, cv::Scalar(0, 0, 0));
10         cv::Mat temp(src.rows, src.cols, CV_8UC1);
11         cv::Mat out[] = {temp_bgr};
12         int from_to[] = {i, i};
13         cv::mixChannels(&src, 1, out, 1, from_to, 1);
14         cv::imshow("single channel", temp_bgr);
15         cv::waitKey(0);
16     }
17 
18     return 0;
19 }

转换到HSV颜色空间查看效果

 1 #include <iostream>
 2 #include <opencv2/opencv.hpp>
 3 #include "opencv2/highgui/highgui.hpp"
 4 #include "opencv2/imgproc/imgproc.hpp"
 5 
 6 int main(int argc, char **argv) {
 7     cv::Mat src = cv::imread("/home/cv/Downloads/images/P1180141.JPG", 1);
 8     cv::resize(src, src, cv::Size(src.cols / 3, src.rows / 3), cv::INTER_CUBIC);
 9     cv::imshow("original_after_resize", src);
10     
11     cv::Mat img_hsv;
12     cv::cvtColor(src, img_hsv, CV_BGR2HSV);
13     cv::Mat dst;
14     dst.create(img_hsv.size(), img_hsv.depth());
15 
16     int ch[] = {0, 0};
17     int ch1[] = {1, 0};
18     int ch2[] = {2, 0};
19 
20     // Hue 色调通道
21     cv::mixChannels(&img_hsv, 1, &dst, 1, ch, 1);
22     cv::imshow("hsv-h", dst);
23     // Saturation 饱和度通道
24     cv::mixChannels(&img_hsv, 1, &dst, 1, ch1, 1);
25     cv::imshow("hsv-s", dst);
26     // Lightness/Value 亮度/像素值通道
27     cv::mixChannels(&img_hsv, 1, &dst, 1, ch2, 1);
28     cv::imshow("hsv-v", dst);
29     cv::waitKey(0);
30 
31     return 0;
32 }

转换到YUV空间或YCrCb空间查看效果

 1 #include <iostream>
 2 #include <vector>
 3 #include <opencv2/opencv.hpp>
 4 #include "opencv2/highgui/highgui.hpp"
 5 #include "opencv2/imgproc/imgproc.hpp"
 6  
 7 int main(int argc, char **argv) {
 8     cv::Mat src = cv::imread("/home/cv/Downloads/images/P1180141.JPG", 1);
 9     cv::resize(src, src, cv::Size(src.cols / 3, src.rows / 3), cv::INTER_CUBIC);
10     cv::imshow("original_after_resize", src);
11     
12     // YUV color space
13     cv::Mat img_yuv;
14     cv::cvtColor(src, img_yuv, CV_BGR2YUV);
15     cv::Mat dst;
16     dst.create(img_yuv.size(), img_yuv.depth());
17 
18     // Luminance, 明亮度,灰度值
19     int ch[] = {0, 0};
20     cv::mixChannels(&img_yuv, 1, &dst, 1, ch, 1);
21     cv::imshow("yuv-y", dst);
22     // Chrominance, 色彩及饱和度,指定像素的颜色
23     int ch1[] = {1, 0};
24     cv::mixChannels(&img_yuv, 1, &dst, 1, ch1, 1);
25     cv::imshow("yuv-u", dst);
26     int ch2[] = {2, 0};
27     cv::mixChannels(&img_yuv, 1, &dst, 1, ch2, 1);
28     cv::imshow("yuv-v", dst);
29 
30     // YCrCb color space
31     cv::Mat ycrb;
32     cv::cvtColor(src, ycrb, CV_BGR2YCrCb);
33     std::vector<cv::Mat> mv;
34     cv::split(ycrb, (std::vector<cv::Mat>&) mv);
35 
36     // Y channel
37     cv::Mat chy(src.rows, src.cols, CV_8UC1);
38     chy = mv[0].clone();
39     cv::imshow("Y", chy);
40     // Cr and Cb channel
41     // Cr反映RGB输入信号红色部分与RGB信号亮度值之间的差异
42     // Cb反应RGB输入信号蓝色部分与RGB信号亮度值之间的差异
43     cv::Mat chu(src.rows, src.cols, CV_8UC1);
44     chu = mv[1].clone();
45     cv::imshow("Cr", chu);
46     cv::Mat chv(src.rows, src.cols, CV_8UC1);
47     chv = mv[2].clone();
48     cv::imshow("Cb", chv);
49     cv::waitKey(0);
50 
51     return 0;
52 }
  •  cv::Mat 类型的成员函数 depth 

查看官方文档

inline
int Mat::depth() const
{
    return CV_MAT_DEPTH(flags);
}

其中的 CV_MAT_DEPTH 定义如下

#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)

这里的 CV_MAT_DEPTH_MASK 定义如下

#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)

宏定义中的 CV_DEPTH_MAX 定义如下

#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)

Mat::type
Returns the type of a matrix element.

C++: int Mat::type() const
The method returns a matrix element type. This is an identifier compatible with the CvMat type system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.

表格来源(OpenCV学习十七:OpenCV中Mat的type)

出处暂不可考

Mat::depth
Returns the depth of a matrix element.

C++: int Mat::depth() const
The method returns the identifier of the matrix element depth (the type of each individual channel). For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of matrix types contains the following values:

 

#define CV_8U 0
#define CV_8S 1
#define CV_16U 2
#define CV_16S 3
#define CV_32S 4
#define CV_32F 5
#define CV_64F 6
#define CV_USRTYPE1 7

 

CV_8U - 8-bit unsigned integers ( 0..255 )
CV_8S - 8-bit signed integers ( -128..127 )
CV_16U - 16-bit unsigned integers ( 0..65535 )
CV_16S - 16-bit signed integers ( -32768..32767 )
CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )

转换函数

void cv::transform (InputArray src,
    OutputArray dst,
    InputArray m
)

The function cv::transform performs the matrix transformation of every element of the array src and stores the results in dst :

𝚍𝚜𝚝(I)=𝚖⋅𝚜𝚛𝚌(I)    (when m.cols=src.channels()), or

𝚍𝚜𝚝(I)=𝚖⋅[𝚜𝚛𝚌(I);1]    (when m.cols=src.channels()+1)

Every element of the N-channel array src is interpreted as N-element vector that is transformed using the MxN or Mx(N+1) matrix m to M-element vector - the corresponding element of the output array dst.

The function may be used for geometrical transformation of N-dimensional points, arbitrary linear color space transformation(such as various kinds of RGB to YUV transforms), shuffling the image channels, and so forth.

Parameters
    src    input array that must have as many channels(1 to 4) as m.cols or m.cols-1.
    dst    output array of the same size and depth as src; it has as many channels as m.rows.
    m    transformation 2x2 or 2x3 floating-point matrix.
  • 以切片方式读取cv::Mat

读取矩阵中指定区域内的数据, OpenCV 有提供一种切片操作

template<typename _Tp> class Rect_
{
    public:
    typedef _Tp value_type;

    //! default constructor
    Rect_();
    Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
    Rect_(const Rect_& r);
    Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
    Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);

    Rect_& operator = ( const Rect_& r );
    //! the top-left corner
    Point_<_Tp> tl() const;
    //! the bottom-right corner
    Point_<_Tp> br() const;

    //! size (width, height) of the rectangle
    Size_<_Tp> size() const;
    //! area (width*height) of the rectangle
    _Tp area() const;
    //! true if empty
    bool empty() const;

    //! conversion to another data type
    template<typename _Tp2> operator Rect_<_Tp2>() const;

    //! checks whether the rectangle contains the point
    bool contains(const Point_<_Tp>& pt) const;

    _Tp x; //!< x coordinate of the top-left corner
    _Tp y; //!< y coordinate of the top-left corner
    _Tp width; //!< width of the rectangle
    _Tp height; //!< height of the rectangle
};

typedef Rect_<int> Rect2i;
typedef Rect_<float> Rect2f;
typedef Rect_<double> Rect2d;
typedef Rect2i Rect;
cv::Rect
cv::Rect(int x, int y, int width, int height)

其中xy分别表示所取区域的其实坐标, width 和 height 分别表示所取区域的宽度和高度。例如

(cv::Mat(cv::Size(500, 500), CV_8UC1, cv::Scalar(0.0f)))(cv::Rect(0, 0, 100, 25))

就表示取原矩阵中以 (0, 0) 为起点,宽100高25的区域。

未完待续……

posted @ 2019-06-11 14:32  coffee_tea_or_me  阅读(985)  评论(0编辑  收藏  举报