• OpenCV学习(7.16)


    写了个实现摄像头上画线并输出角度的东西……虽然很简单,但脑残的我还是debug了很长时间。

     1 // 圆和直线.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 
     6 using namespace std;
     7 using namespace cv;
     8 
     9 void onMouse(int event, int x, int y, int flags, void* param);
    10 
    11 Mat frame;
    12 Point p1, p2;
    13 bool flag = true;
    14 
    15 int main()
    16 {
    17   VideoCapture capture;
    18   capture.open(0);
    19 
    20   namedWindow("test", WINDOW_AUTOSIZE);
    21   setMouseCallback("test", onMouse);
    22 
    23   while (1)
    24   {
    25     capture >> frame;
    26     line(frame, p1, p2, 0, 1, 8, 0);
    27     imshow("test", frame);
    28     waitKey(33);
    29   }
    30   return 0;
    31 }
    32 
    33 void onMouse(int event, int x, int y, int flags, void* param)
    34 {
    35 
    36   switch (event)
    37   {
    38   case CV_EVENT_MOUSEMOVE:
    39     if (flag == true) { p1.x = x; p1.y = y - 50; p2.x = x; p2.y = y + 50; }
    40     else { p2.x = x; p2.y = y; }
    41     break;
    42   case CV_EVENT_LBUTTONDOWN:
    43     flag = false; p1.x = x; p1.y = y; break;
    44   case CV_EVENT_LBUTTONUP:
    45     int X = x - p1.x, Y = p1.y - y;
    46     double r = sqrt(fabs(X*X) + fabs(Y*Y));
    47     //cout <<X << ' ' << Y << endl;
    48     double e = 180.0 / 3.1415926, line_degree;
    49     if (X > 0)
    50     {
    51       if (Y >= 0) line_degree = asin(Y / r)*e;
    52       else line_degree = asin(Y / r)*e;
    53     }
    54     else if (X < 0)
    55     {
    56     if (Y >= 0) line_degree = 180-asin(Y / r)*e;
    57     else line_degree = -asin(Y / r)*e - 180.0;
    58     }
    59   cout << "角度=" << line_degree << endl;
    60   flag = true;
    61   break;
    62   }
    63   return;
    64 }

    鼠标标识掩膜:
    实现比较简单……就是新建一个图片,在那个图片中画圆,需要的时候用addweight函数把两张照片融合到一起,但是因为我掌握了直接画圆的技术所以就不需要这个了。

    串口通信程序:
    这个地方似乎要用到C#。在VS中写C#的话就需要在:
    “属性管理器”->“配置属性”->“常规”->“公共语言运行时支持”中选择“公共语言运行时支持”。
    但打开公共支持之后还是不行……
    //////////
    好的,要打开“属性管理器”,在“配置”处选择“所有配置”。


    下面的代码是从Microsoft的官网上拿来的例程,但注释是我自己写得。主要原因是学长从网上找的是C#的例程,而我找的是C++程序。
    写了一堆注释……定义了一些初始值。

    // 串口通信C++.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #using <System.dll>//程序集
    
    using namespace System;
    using namespace System::IO::Ports;
    using namespace System::Threading;
    
    public ref class PortChat
    {
    private:
    static bool _continue;
    static SerialPort^ _serialPort;
    
    public:
    static void Main()
    {
    String^ name;//“^”表示声明一个托管类型的字符串指针。特点是内存由GC管理,占用的内存会被自动释放
    String^ message;
    StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;//表示一种字符串比较操作,该操作使用特定的大小写以及基于区域性的比较规则或序号比较规则。
    Thread^ readThread = gcnew Thread(gcnew ThreadStart(PortChat::Read));//新建线程
    
    // Create a new SerialPort object with default settings.
    _serialPort = gcnew SerialPort();
    
    // 设置各种数据
    _serialPort->PortName = SetPortName("COM3");//设置通信湍口(这里可以用COM端口)
    _serialPort->BaudRate = SetPortBaudRate(9600);//设置串行波特率
    _serialPort->Parity = SetPortParity(Parity::None);//设置奇偶校验检查协议
    _serialPort->DataBits = SetPortDataBits(8);//设置每个字节的标准数据位长度
    _serialPort->StopBits = SetPortStopBits(StopBits::One);//设置标准停止位数
    //_serialPort->Handshake = SetPortHandshake(_serialPort->Handshake);//设置串行端口数据传输的握手协议
    
    // Set the read/write timeouts
    //_serialPort->ReadTimeout = 500;//设置读取操作未完成时发生超时之前的毫秒数
    //_serialPort->WriteTimeout = 500;//设置写入操作未完成时发生超时之前的毫秒数
    
    _serialPort->Open();//打开端口
    _continue = true;//是否继续传输
    //readThread->Start();
    
    //Console::Write("Name: ");//console即控制台。似乎这句话的意思是输出到控制台
    name = Console::ReadLine();//一直读取到输入缓冲区中的 NewLine 值。
    //SerialPort::NewLine 属性 
    //获取或设置用于解释 ReadLine 和 WriteLine 方法调用结束的值。
    //表示行尾的值,默认值为换行符。
    //Console::WriteLine("Type QUIT to exit");
    
    while (_continue)
    {
    message = Console::ReadLine();
    
    if (stringComparer->Equals("quit", message))//如果是quit就退出(话说前面明明说的是大写……)
    {
    _continue = false;
    }
    else
    {
    _serialPort->WriteLine(//将指定的字符串和NewLine值写入输出缓冲区
    String::Format("<{0}>: {1}", name, message));
    //String::Format用来生成一个静态字符串
    //此处生成的应该是:“<name>:message”
    }
    }
    
    readThread->Join();//令线程处于阻塞状态
    _serialPort->Close();//关闭串口
    }
    
    static void Read()
    {
    while (_continue)
    {
    try
    {
    String^ message = _serialPort->ReadLine();
    Console::WriteLine(message);
    }
    catch (TimeoutException ^) {}//超时的话就算是发生了错误……是这个意思吧
    }
    }
    
    static String^ SetPortName(String^ defaultPortName)
    {
    String^ portName;
    
    Console::WriteLine("Available Ports:");
    for each (String^ s in SerialPort::GetPortNames())
    {
    Console::WriteLine(" {0}", s);
    }
    
    Console::Write("Enter COM port value (Default: {0}): ", defaultPortName);
    portName = Console::ReadLine();
    
    if (portName == "")
    {
    portName = defaultPortName;
    }
    return portName;
    }
    
    static Int32 SetPortBaudRate(Int32 defaultPortBaudRate)
    {
    String^ baudRate;
    
    Console::Write("Baud Rate(default:{0}): ", defaultPortBaudRate);
    baudRate = Console::ReadLine();
    
    if (baudRate == "")
    {
    baudRate = defaultPortBaudRate.ToString();
    }
    
    return Int32::Parse(baudRate);
    }
    
    static Parity SetPortParity(Parity defaultPortParity)
    {
    String^ parity;
    
    Console::WriteLine("Available Parity options:");
    for each (String^ s in Enum::GetNames(Parity::typeid))
    {
    Console::WriteLine(" {0}", s);
    }
    
    Console::Write("Enter Parity value (Default: {0}):", defaultPortParity.ToString());
    parity = Console::ReadLine();
    
    if (parity == "")
    {
    parity = defaultPortParity.ToString();
    }
    
    return (Parity)Enum::Parse(Parity::typeid, parity);
    }
    
    static Int32 SetPortDataBits(Int32 defaultPortDataBits)
    {
    String^ dataBits;
    
    Console::Write("Enter DataBits value (Default: {0}): ", defaultPortDataBits);
    dataBits = Console::ReadLine();
    
    if (dataBits == "")
    {
    dataBits = defaultPortDataBits.ToString();
    }
    
    return Int32::Parse(dataBits);
    }
    
    static StopBits SetPortStopBits(StopBits defaultPortStopBits)
    {
    String^ stopBits;
    
    Console::WriteLine("Available Stop Bits options:");
    for each (String^ s in Enum::GetNames(StopBits::typeid))//for each可以理解为for语句对特定数据结构的遍历过程的优化……
    {
    Console::WriteLine(" {0}", s);
    }
    
    Console::Write("Enter StopBits value (None is not supported and 
    " +
    "raises an ArgumentOutOfRangeException. 
     (Default: {0}):", defaultPortStopBits.ToString());
    stopBits = Console::ReadLine();
    
    if (stopBits == "")
    {
    stopBits = defaultPortStopBits.ToString();
    }
    
    return (StopBits)Enum::Parse(StopBits::typeid, stopBits);
    }
    
    static Handshake SetPortHandshake(Handshake defaultPortHandshake)
    {
    String^ handshake;
    
    Console::WriteLine("Available Handshake options:");
    for each (String^ s in Enum::GetNames(Handshake::typeid))
    {
    Console::WriteLine(" {0}", s);
    }
    
    Console::Write("Enter Handshake value (Default: {0}):", defaultPortHandshake.ToString());
    handshake = Console::ReadLine();
    
    if (handshake == "")
    {
    handshake = defaultPortHandshake.ToString();
    }
    
    return (Handshake)Enum::Parse(Handshake::typeid, handshake);}
    //这个协议感觉可能和加密有关?
    };
    
    int main()
    {
    PortChat::Main();
    }

     

     

     

     

  • 相关阅读:
    requests+lxml+xpath爬取豆瓣电影
    hisi出的H264码流结构
    单片机复位电路原理介绍
    二极管与、或门,三极管非门电路原理
    Windows Route 路由表命令整理
    理解Windows中的路由表和默认网关
    Windows路由表详解
    linux 路由表设置 之 route 指令详解
    linux中service *** start与直接运行/usr/bin/***的区别
    Linux运行与控制后台进程的方法:nohup, setsid, &, disown, screen
  • 原文地址:https://www.cnblogs.com/Shymuel/p/9327516.html
Copyright © 2020-2023  润新知