折騰好久, 終於發現大廠的文檔也堪稱混亂. 首先:要用騰訊AI有兩個網址可以註冊, 算是2種方案, 第一個 https://ai.qq.com/product/face.shtml#shape , 這個我不推薦. 估計是舊版本吧, 用起來很不方便. 這個網址註冊出來, 會給每個應用分配一個APPID 和 APPKEY, 格式爲: APPID : 2125xxxxxx , APPKEY: jgzPJhxndVxxxxxx , 注意長度明顯和下文中註冊得到的不一樣. 要求自己按文檔格式實現HTTP訪問的諸多字符串準備, 編程很麻煩.
真正好用的是第二種方法, 在騰訊雲上直接註冊得到的, 網址是: https://cloud.tencent.com/act/event/aiAllFree#mod-hot2
不管你用哪個服務, 隨便點一個接入服務, 比如我點擊五官定位, 先得到 SecretId 和 SecretKey , 之後再點接入其他服務, 比如我用了"錄音文件識別"和"五官定位", 在這2個服務下面都點了"0元接入" , 否則後面運行程序會提示出錯的. 所有應用都用同一個secretid和secretKey, 在賬號名字上點擊, 出現下圖, 點擊"項目管理"
再點擊訪問密鑰
新建密鑰
用的是這個SecretID(長度36字符)和SecretKey(長度32), 把這個問題搞清楚, 下面的都很簡單了. 我一直以爲要第一個網址上註冊得到的短ID和key, 浪費不少時間.
打開vs2015 , 新建一個C# winform項目, , vs菜單:工具->Nuget 管理器->管理解決方案的NuGet程序包, 安裝TencentCloudSDK v3.0.42, emgu.cv, newtonjson等
騰訊雲原始SDK的例子,完全把人搞懵,我要語音識別,五官定位,你叫我先整明白啥叫cvm? 虛擬主機和AI天壤之別好嗎? 所有代碼中的註釋都完全一樣.廢話註釋還特別多, 從百十行重複廢話註釋中尋找5,6行有用的代碼. 真不敢相信大廠能這麼寫代碼. 刪除掉註釋後發現其實騰訊SDK真的用起來好簡單, 所有應用使用同一個ID和KEY, 下面的代碼實現了cvm主機查詢(原廠例子), 語音mp3識別文字, 五官定位並顯示3個功能. 記錄下來防止走彎路. 注意裏面的ID/KEY替換成自己的,否則提示鑑權錯誤.
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using TencentCloud.Common;
using TencentCloud.Common.Profile;
using TencentCloud.Cvm.V20170312;
using TencentCloud.Cvm.V20170312.Models;
using TencentCloud.Aai.V20180522;
using TencentCloud.Aai.V20180522.Models;
using TencentCloud.Iai.V20180301;
using TencentCloud.Iai.V20180301.Models;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
namespace WindowsFormsApp1
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private async Task<string> GetZones()
{
try
{
// 必要步驟: // 騰訊雲賬戶密鑰對secretId,secretKey。
// 下面全部應當替換成自己的ID和key才能運行.
Credential cred = new Credential
{
SecretId = "AKIDEdw5zjxxxxxxxxxxxxxxxxxxxxxxxxxx",
SecretKey = "5FBsKbkxxxxxxxxxxxxxxxxxxxxxxxxx"
};
// 實例化一個client, 不必要的選項都屏蔽
ClientProfile clientProfile = new ClientProfile();
HttpProfile httpProfile = new HttpProfile();
// 代理服務器,當你的環境下有代理服務器時設定
httpProfile.WebProxy = Environment.GetEnvironmentVariable("HTTPS_PROXY");
clientProfile.HttpProfile = httpProfile;
// 實例化要請求產品(以cvm爲例)的client對象
CvmClient client = new CvmClient(cred, "ap-guangzhou", clientProfile);
DescribeZonesRequest req = new DescribeZonesRequest();
DescribeZonesResponse resp = await client.DescribeZones(req);
// 輸出json格式的字符串回包
return AbstractModel.ToJsonString(resp);
} catch (Exception e)
{
return e.ToString();
}
}
private async void Button1_Click(object sender, EventArgs e)
{
var result = await GetZones();
textBox1.Text = result;
}
private async void btnMp3ToTxt_Click(object sender, EventArgs e)
{
txtBoxMp3.Text = "";
var result = await GetTxtFromMp3( txtBoxFileName.Text);
txtBoxMp3.Text = result;
}
private async Task<string> GetTxtFromMp3(string strFullPathMp3FileName)
{
try
{
// 必要步驟:騰訊雲賬戶密鑰對secretId,secretKey。
Credential cred = new Credential
{
SecretId = "AKIDEdw5zjxxxxxxxxxxxxxxxxxxxxxxxxxx",
SecretKey = "5FBsKbkxxxxxxxxxxxxxxxxxxxxxxxxx"
};
// 實例化一個client選項
ClientProfile clientProfile = new ClientProfile();
HttpProfile httpProfile = new HttpProfile();
clientProfile.HttpProfile = httpProfile;
AaiClient client = new AaiClient(cred, "ap-guangzhou", clientProfile);
//開始語音mp3轉文字, 成對使用 SentenceRecognitionRequest/ SentenceRecognitionResponse
SentenceRecognitionRequest req = new SentenceRecognitionRequest();
string strFilepath = strFullPathMp3FileName;
FileStream fs = new FileStream(strFilepath, FileMode.Open);
byte[] raw = new byte[fs.Length];
fs.Read(raw, 0, raw.Length);
string base64data = Convert.ToBase64String(raw); //mp3文件的數據用Base64編碼
fs.Close();
// 語音識別request的設置。
req.ProjectId = 0;
req.SubServiceType = 2;
//必須8或16k否則返回不接受,但實際文件32k/64k也能接受,但會識別錯誤
req.EngSerViceType = "16k";
req.SourceType = 1;
req.VoiceFormat = "mp3";
//隨便輸,系統其實沒返回這個ID,和文檔不一樣
req.UsrAudioKey = "my_usrid_5c79510a12da-whatever";
//base64編碼數據設置爲該Request的Data
req.Data = base64data;
req.DataLen = base64data.Length;
// 異步提交語言識別Request
SentenceRecognitionResponse resp = await client.SentenceRecognition(req);
// 輸出json格式的字符串回包
return AbstractModel.ToJsonString(resp);
}
catch (Exception e)
{
return e.ToString();
}
}
private void btnOpenMp3_Click(object sender, EventArgs e)
{ // 打開mp3文件對話框
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
txtBoxFileName.Text = ofd.FileName;
}
}
private void btnOpenPic_Click(object sender, EventArgs e)
{ // 打開圖片文件對話框
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
txtBoxPic.Text = ofd.FileName;
}
}
private async void btnFaceMarks_Click(object sender, EventArgs e)
{
txtBoxAnalyzeFaceResult.Text = "";
var result = await GetFaceMarks(txtBoxPic.Text);
txtBoxAnalyzeFaceResult.Text = result; //人臉json顯示到textbox
}
private async Task<string> GetFaceMarks(string strFullPathPicFileName)
{
try
{
// 必要步驟: // 騰訊雲賬戶密鑰對secretId,secretKey。
Credential cred = new Credential
{
SecretId = "AKIDEdw5zjxxxxxxxxxxxxxxxxxxxxxxxxxx",
SecretKey = "5FBsKbkxxxxxxxxxxxxxxxxxxxxxxxxx"
};
// 實例化一個client選項
ClientProfile clientProfile = new ClientProfile();
HttpProfile httpProfile = new HttpProfile();
clientProfile.HttpProfile = httpProfile;
IaiClient client = new IaiClient(cred, "ap-guangzhou", clientProfile);
//這裏開始 anlyzeFace ,五官定位, 成對使用 AnalyzeFaceRequest/ AnalyzeFaceResponse
AnalyzeFaceRequest faceReq = new AnalyzeFaceRequest() ;
if ( txtPicUrl.Text.Length>0 )
{ // 若faceReq同時有url和Image, 騰訊雲優先用url.
faceReq.Url = txtPicUrl.Text;
} else
{
if ( strFullPathPicFileName.Length>0 )
{ // 用filestream 讀取本地圖片文件
string strFilepath = strFullPathPicFileName;
FileStream fs = new FileStream(strFilepath, FileMode.Open);
byte[] raw = new byte[fs.Length];
fs.Read(raw, 0, raw.Length);
string base64data = Convert.ToBase64String(raw); //圖片文件的數據用Base64編碼
fs.Close();
faceReq.Image = base64data; // base64編碼後的字符串設置爲Request的Image
}
else
{
MessageBox.Show("請選擇一個本地圖片或在下框輸入圖片網址");
return "";
}
}
// 異步方式發出request, 等待結果
AnalyzeFaceResponse resp = await client.AnalyzeFace( faceReq);
// 輸出json格式的字符串回包
return AbstractModel.ToJsonString(resp);
}
catch (Exception e)
{
return e.ToString();
}
}
private async void btnGetJsonDrawPic_Click(object sender, EventArgs e)
{ // 解析五官定位的json數據並用opencv畫出.
string strJson = txtBoxAnalyzeFaceResult.Text;
JObject joResult = (JObject)JsonConvert.DeserializeObject(strJson);
// 圖像的寬度高度
int iWidth = Convert.ToInt32(joResult["ImageWidth"].ToString() );
int iHeight = Convert.ToInt32(joResult["ImageHeight"].ToString());
string strReqId = joResult["RequestId"].ToString();
Mat src = new Mat(txtBoxPic.Text); // OpenCV 準備顯示照片
MCvScalar ptColorRed = new Bgr(0, 0, 255).MCvScalar; // 標誌點設置爲紅色
MCvScalar ptColorBlue = new Bgr(255, 0, 0).MCvScalar; // 文字設置爲藍色
// 臉型數據
string strFaceShapeSet = joResult["FaceShapeSet"].ToString();
JArray jarFaceShpSet = (JArray)JsonConvert.DeserializeObject(strFaceShapeSet);
//獲得FaceShapeSet對象的所有字段名
var itemShpSetFieldName = ((JObject)jarFaceShpSet[0]).Properties().ToList();
foreach (var itemField in itemShpSetFieldName)
{
string itemName = itemField.Name.ToString();
string itemValue = itemField.Value.ToString();
JArray jarItemDetial = (JArray)JsonConvert.DeserializeObject(itemValue);
// 把每個字段下的標誌點畫圓形或顯示編號到照片上. 每段從0開始編號
int iIndex = 0;
foreach (var item in jarItemDetial)
{
System.Drawing.Point pt = new System.Drawing.Point(
Convert.ToInt32(item["X"].ToString()),
Convert.ToInt32(item["Y"].ToString()));
CvInvoke.Circle(src, pt, 1 , ptColorRed , 2); // 畫圓點
//System.Drawing.Point pt2 = new System.Drawing.Point();
// pt2 = pt;
// pt2.Offset(1, 1); //錯開一個像素,否則Line畫不出來
// CvInvoke.Line(src,pt, pt2 , ptColorRed); // 用畫線代替畫點,在emgucv裏修改一個像素點麻煩,不如直接畫線,畫圓太大
CvInvoke.PutText(src, iIndex.ToString(), pt, FontFace.HersheyComplex, 0.4, ptColorBlue); // 顯示編號,縮小到0.4顯示
CvInvoke.Imshow("test", src);
CvInvoke.WaitKey(50); // 50ms 刷一幀, 動畫效果顯示
iIndex++;
}
}
//CvInvoke.Resize(src, src ,new Size(src.Width * 2 , src.Height * 2) ); //圖片中臉部太小就resize看結果,大臉圖不用
// CvInvoke.Imshow("test", src);
}
private void btnShowImg_Click(object sender, EventArgs e)
{ // 測試emgu.cv
Mat src = new Mat(txtBoxPic.Text);
CvInvoke.Circle(src, new System.Drawing.Point(50, 50), 20, new Bgr(0, 0, 255).MCvScalar, 2);
CvInvoke.Imshow("test", src);
}
private void btnShowPngAlpha_Click(object sender, EventArgs e)
{
// Mat image = new Mat(txtBoxPic.Text);
}
}
比較逼真的漫畫人物也能識別, 2個瞳孔也識別了, 這個還是可以的. 稍微不足的是發跡線沒有識別.
MainForm Design的代碼 , 對了,囉嗦一句,如果使用網址圖片, 應當不會正確畫圖, 但是解析Json數據都正確 因我沒有把圖片下載本地, 以後去完善吧. 要顯示圖片是點擊裏面的"解析json" 按鈕, "ShowImg" 按鈕只是測試
namespace WindowsFormsApp1
{
partial class MainForm
{
/// <summary>
/// 必需的設計器變量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
/// <param name="disposing">如果應釋放託管資源,爲 true;否則爲 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗體設計器生成的代碼
/// <summary>
/// 設計器支持所需的方法 - 不要修改
/// 使用代碼編輯器修改此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.btnMp3ToTxt = new System.Windows.Forms.Button();
this.txtBoxMp3 = new System.Windows.Forms.TextBox();
this.btnOpenMp3 = new System.Windows.Forms.Button();
this.txtBoxFileName = new System.Windows.Forms.TextBox();
this.btnOpenPic = new System.Windows.Forms.Button();
this.txtBoxPic = new System.Windows.Forms.TextBox();
this.btnFaceMarks = new System.Windows.Forms.Button();
this.txtBoxAnalyzeFaceResult = new System.Windows.Forms.TextBox();
this.txtPicUrl = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btnGetJsonDrawPic = new System.Windows.Forms.Button();
this.btnShowImg = new System.Windows.Forms.Button();
this.btnShowPngAlpha = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Font = new System.Drawing.Font("宋體", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button1.Location = new System.Drawing.Point(478, 13);
this.button1.Margin = new System.Windows.Forms.Padding(4);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(144, 30);
this.button1.TabIndex = 0;
this.button1.Text = "GetZones";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.Button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(-1, 0);
this.textBox1.Margin = new System.Windows.Forms.Padding(4);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(471, 88);
this.textBox1.TabIndex = 1;
//
// btnMp3ToTxt
//
this.btnMp3ToTxt.Location = new System.Drawing.Point(471, 95);
this.btnMp3ToTxt.Name = "btnMp3ToTxt";
this.btnMp3ToTxt.Size = new System.Drawing.Size(130, 41);
this.btnMp3ToTxt.TabIndex = 2;
this.btnMp3ToTxt.Text = "語音MP3轉文字";
this.btnMp3ToTxt.UseVisualStyleBackColor = true;
this.btnMp3ToTxt.Click += new System.EventHandler(this.btnMp3ToTxt_Click);
//
// txtBoxMp3
//
this.txtBoxMp3.Location = new System.Drawing.Point(-1, 142);
this.txtBoxMp3.Multiline = true;
this.txtBoxMp3.Name = "txtBoxMp3";
this.txtBoxMp3.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtBoxMp3.Size = new System.Drawing.Size(623, 98);
this.txtBoxMp3.TabIndex = 3;
//
// btnOpenMp3
//
this.btnOpenMp3.Location = new System.Drawing.Point(366, 95);
this.btnOpenMp3.Name = "btnOpenMp3";
this.btnOpenMp3.Size = new System.Drawing.Size(75, 41);
this.btnOpenMp3.TabIndex = 4;
this.btnOpenMp3.Text = "Open";
this.btnOpenMp3.UseVisualStyleBackColor = true;
this.btnOpenMp3.Click += new System.EventHandler(this.btnOpenMp3_Click);
//
// txtBoxFileName
//
this.txtBoxFileName.Location = new System.Drawing.Point(-1, 95);
this.txtBoxFileName.Multiline = true;
this.txtBoxFileName.Name = "txtBoxFileName";
this.txtBoxFileName.Size = new System.Drawing.Size(361, 38);
this.txtBoxFileName.TabIndex = 5;
//
// btnOpenPic
//
this.btnOpenPic.Location = new System.Drawing.Point(385, 246);
this.btnOpenPic.Name = "btnOpenPic";
this.btnOpenPic.Size = new System.Drawing.Size(56, 34);
this.btnOpenPic.TabIndex = 6;
this.btnOpenPic.Text = "Open";
this.btnOpenPic.UseVisualStyleBackColor = true;
this.btnOpenPic.Click += new System.EventHandler(this.btnOpenPic_Click);
//
// txtBoxPic
//
this.txtBoxPic.Location = new System.Drawing.Point(-1, 246);
this.txtBoxPic.Multiline = true;
this.txtBoxPic.Name = "txtBoxPic";
this.txtBoxPic.Size = new System.Drawing.Size(380, 34);
this.txtBoxPic.TabIndex = 7;
this.txtBoxPic.Text = "E:\\Drawings\\臉部照片\\test_1.jpg";
//
// btnFaceMarks
//
this.btnFaceMarks.Location = new System.Drawing.Point(449, 246);
this.btnFaceMarks.Name = "btnFaceMarks";
this.btnFaceMarks.Size = new System.Drawing.Size(75, 35);
this.btnFaceMarks.TabIndex = 8;
this.btnFaceMarks.Text = "五官定位";
this.btnFaceMarks.UseVisualStyleBackColor = true;
this.btnFaceMarks.Click += new System.EventHandler(this.btnFaceMarks_Click);
//
// txtBoxAnalyzeFaceResult
//
this.txtBoxAnalyzeFaceResult.Location = new System.Drawing.Point(-1, 332);
this.txtBoxAnalyzeFaceResult.Multiline = true;
this.txtBoxAnalyzeFaceResult.Name = "txtBoxAnalyzeFaceResult";
this.txtBoxAnalyzeFaceResult.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtBoxAnalyzeFaceResult.Size = new System.Drawing.Size(623, 180);
this.txtBoxAnalyzeFaceResult.TabIndex = 9;
//
// txtPicUrl
//
this.txtPicUrl.Location = new System.Drawing.Point(141, 287);
this.txtPicUrl.Multiline = true;
this.txtPicUrl.Name = "txtPicUrl";
this.txtPicUrl.Size = new System.Drawing.Size(492, 39);
this.txtPicUrl.TabIndex = 10;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(10, 290);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(121, 15);
this.label1.TabIndex = 11;
this.label1.Text = "或優先用Pic網址";
//
// btnGetJsonDrawPic
//
this.btnGetJsonDrawPic.Location = new System.Drawing.Point(530, 247);
this.btnGetJsonDrawPic.Name = "btnGetJsonDrawPic";
this.btnGetJsonDrawPic.Size = new System.Drawing.Size(80, 33);
this.btnGetJsonDrawPic.TabIndex = 12;
this.btnGetJsonDrawPic.Text = "解析Json";
this.btnGetJsonDrawPic.UseVisualStyleBackColor = true;
this.btnGetJsonDrawPic.Click += new System.EventHandler(this.btnGetJsonDrawPic_Click);
//
// btnShowImg
//
this.btnShowImg.Location = new System.Drawing.Point(514, 518);
this.btnShowImg.Name = "btnShowImg";
this.btnShowImg.Size = new System.Drawing.Size(96, 25);
this.btnShowImg.TabIndex = 13;
this.btnShowImg.Text = "ShowImg";
this.btnShowImg.UseVisualStyleBackColor = true;
this.btnShowImg.Click += new System.EventHandler(this.btnShowImg_Click);
//
// btnShowPngAlpha
//
this.btnShowPngAlpha.Location = new System.Drawing.Point(359, 519);
this.btnShowPngAlpha.Name = "btnShowPngAlpha";
this.btnShowPngAlpha.Size = new System.Drawing.Size(111, 24);
this.btnShowPngAlpha.TabIndex = 14;
this.btnShowPngAlpha.Text = "透明PNG顯示";
this.btnShowPngAlpha.UseVisualStyleBackColor = true;
this.btnShowPngAlpha.Click += new System.EventHandler(this.btnShowPngAlpha_Click);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(635, 555);
this.Controls.Add(this.btnShowPngAlpha);
this.Controls.Add(this.btnShowImg);
this.Controls.Add(this.btnGetJsonDrawPic);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtPicUrl);
this.Controls.Add(this.txtBoxAnalyzeFaceResult);
this.Controls.Add(this.btnFaceMarks);
this.Controls.Add(this.txtBoxPic);
this.Controls.Add(this.btnOpenPic);
this.Controls.Add(this.txtBoxFileName);
this.Controls.Add(this.btnOpenMp3);
this.Controls.Add(this.txtBoxMp3);
this.Controls.Add(this.btnMp3ToTxt);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "MainForm";
this.Text = "Tencent Cloud Demo";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button btnMp3ToTxt;
private System.Windows.Forms.TextBox txtBoxMp3;
private System.Windows.Forms.Button btnOpenMp3;
private System.Windows.Forms.TextBox txtBoxFileName;
private System.Windows.Forms.Button btnOpenPic;
private System.Windows.Forms.TextBox txtBoxPic;
private System.Windows.Forms.Button btnFaceMarks;
private System.Windows.Forms.TextBox txtBoxAnalyzeFaceResult;
private System.Windows.Forms.TextBox txtPicUrl;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnGetJsonDrawPic;
private System.Windows.Forms.Button btnShowImg;
private System.Windows.Forms.Button btnShowPngAlpha;
}
}