HistogramDialog.cs 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331
  1. using OpenCvSharp;
  2. using PaintDotNet.Camera;
  3. using PaintDotNet.CustomControl;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Windows.Forms;
  7. namespace PaintDotNet.Instrument
  8. {
  9. /// <summary>
  10. /// 工具-直方图
  11. /// </summary>
  12. internal class HistogramDialog : FloatingToolForm
  13. {
  14. #region 初始化变量
  15. private AppWorkspace AppWorkspace;
  16. /// <summary>
  17. /// 一个矩阵数组,用来接收直方图,记得全部初始化
  18. /// </summary>
  19. private Mat[] oldHists = new Mat[] { new Mat(), new Mat(), new Mat() };
  20. /// <summary>
  21. /// 灰度图
  22. /// </summary>
  23. private bool isGray = false;
  24. /// <summary>
  25. /// BGR线条颜色
  26. /// </summary>
  27. private Scalar[] color = new Scalar[] { new Scalar(255, 0, 0, 255), new Scalar(0, 255, 0, 255), new Scalar(0, 0, 255, 255) };
  28. /// <summary>
  29. /// 计算gamma的查找表
  30. /// </summary>
  31. private Mat lookUpTable = new Mat(1, 256, MatType.CV_8U);
  32. #endregion
  33. #region 控件相关
  34. private Button button2;
  35. private Button button3;
  36. private Button button4;
  37. private Button button5;
  38. private Label label1;
  39. private Label label2;
  40. private Label label3;
  41. private NumericUpDown numericUpDown1;
  42. private Label label4;
  43. private TriangleTrackBar trackBar1;
  44. private Label label5;
  45. private Label label6;
  46. private TriangleTrackBar trackBar2;
  47. private Label label7;
  48. private TriangleTrackBar trackBar3;
  49. private SelectButton skipButton;
  50. private SelectButton logButton;
  51. private UCTrackBar ucTrackBar1;
  52. private NumericUpDown numericUpDown2;
  53. private PictureBox pictureBox1;
  54. private void InitializeLanguageText()
  55. {
  56. this.button2.Text = PdnResources.GetString("Menu.optimal.text");
  57. this.button4.Text = PdnResources.GetString("Menu.Gammavalue.text") + "0.45";
  58. this.button5.Text = PdnResources.GetString("Menu.Originalstate.text");
  59. this.label1.Text = PdnResources.GetString("Menu.luminance.text") + ":";
  60. this.label2.Text = PdnResources.GetString("Menu.Contrast.text") + ":";
  61. this.label3.Text = PdnResources.GetString("Menu.Gammavalue.text") + ":";
  62. }
  63. private void InitializeComponent()
  64. {
  65. this.pictureBox1 = new System.Windows.Forms.PictureBox();
  66. this.button2 = new System.Windows.Forms.Button();
  67. this.button3 = new System.Windows.Forms.Button();
  68. this.button4 = new System.Windows.Forms.Button();
  69. this.button5 = new System.Windows.Forms.Button();
  70. this.label1 = new System.Windows.Forms.Label();
  71. this.label2 = new System.Windows.Forms.Label();
  72. this.label3 = new System.Windows.Forms.Label();
  73. this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
  74. this.label4 = new System.Windows.Forms.Label();
  75. this.trackBar1 = new PaintDotNet.CustomControl.TriangleTrackBar();
  76. this.label5 = new System.Windows.Forms.Label();
  77. this.label6 = new System.Windows.Forms.Label();
  78. this.trackBar2 = new PaintDotNet.CustomControl.TriangleTrackBar();
  79. this.label7 = new System.Windows.Forms.Label();
  80. this.trackBar3 = new PaintDotNet.CustomControl.TriangleTrackBar();
  81. this.skipButton = new PaintDotNet.CustomControl.SelectButton();
  82. this.logButton = new PaintDotNet.CustomControl.SelectButton();
  83. this.ucTrackBar1 = new PaintDotNet.CustomControl.UCTrackBar();
  84. this.numericUpDown2 = new System.Windows.Forms.NumericUpDown();
  85. ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
  86. ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
  87. ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit();
  88. this.SuspendLayout();
  89. //
  90. // pictureBox1
  91. //
  92. this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
  93. | System.Windows.Forms.AnchorStyles.Left)
  94. | System.Windows.Forms.AnchorStyles.Right)));
  95. this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
  96. this.pictureBox1.Location = new System.Drawing.Point(12, 12);
  97. this.pictureBox1.Name = "pictureBox1";
  98. this.pictureBox1.Size = new System.Drawing.Size(256, 124);
  99. this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
  100. this.pictureBox1.TabIndex = 1;
  101. this.pictureBox1.TabStop = false;
  102. //
  103. // button2
  104. //
  105. this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  106. this.button2.Location = new System.Drawing.Point(126, 274);
  107. this.button2.Name = "button2";
  108. this.button2.Size = new System.Drawing.Size(75, 23);
  109. this.button2.TabIndex = 4;
  110. this.button2.Text = "最佳";
  111. this.button2.UseVisualStyleBackColor = true;
  112. //
  113. // button3
  114. //
  115. this.button3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  116. this.button3.Location = new System.Drawing.Point(241, 303);
  117. this.button3.Name = "button3";
  118. this.button3.Size = new System.Drawing.Size(75, 23);
  119. this.button3.TabIndex = 5;
  120. this.button3.Text = "MIN/MAX";
  121. this.button3.UseVisualStyleBackColor = true;
  122. //
  123. // button4
  124. //
  125. this.button4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  126. this.button4.Location = new System.Drawing.Point(12, 303);
  127. this.button4.Name = "button4";
  128. this.button4.Size = new System.Drawing.Size(75, 23);
  129. this.button4.TabIndex = 6;
  130. this.button4.Text = "伽马值0.45";
  131. this.button4.UseVisualStyleBackColor = true;
  132. //
  133. // button5
  134. //
  135. this.button5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  136. this.button5.Location = new System.Drawing.Point(126, 303);
  137. this.button5.Name = "button5";
  138. this.button5.Size = new System.Drawing.Size(75, 23);
  139. this.button5.TabIndex = 7;
  140. this.button5.Text = "原始状态";
  141. this.button5.UseVisualStyleBackColor = true;
  142. //
  143. // label1
  144. //
  145. this.label1.AutoSize = true;
  146. this.label1.Location = new System.Drawing.Point(25, 166);
  147. this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
  148. this.label1.Name = "label1";
  149. this.label1.Size = new System.Drawing.Size(41, 12);
  150. this.label1.TabIndex = 9;
  151. this.label1.Text = "亮度:";
  152. //
  153. // label2
  154. //
  155. this.label2.AutoSize = true;
  156. this.label2.Location = new System.Drawing.Point(13, 202);
  157. this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
  158. this.label2.Name = "label2";
  159. this.label2.Size = new System.Drawing.Size(53, 12);
  160. this.label2.TabIndex = 10;
  161. this.label2.Text = "对比度:";
  162. //
  163. // label3
  164. //
  165. this.label3.AutoSize = true;
  166. this.label3.Location = new System.Drawing.Point(13, 238);
  167. this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
  168. this.label3.Name = "label3";
  169. this.label3.Size = new System.Drawing.Size(53, 12);
  170. this.label3.TabIndex = 11;
  171. this.label3.Text = "伽马值:";
  172. //
  173. // numericUpDown1
  174. //
  175. this.numericUpDown1.Location = new System.Drawing.Point(242, 276);
  176. this.numericUpDown1.Margin = new System.Windows.Forms.Padding(2);
  177. this.numericUpDown1.Maximum = new decimal(new int[] {
  178. 499,
  179. 0,
  180. 0,
  181. 0});
  182. this.numericUpDown1.Name = "numericUpDown1";
  183. this.numericUpDown1.Size = new System.Drawing.Size(50, 21);
  184. this.numericUpDown1.TabIndex = 12;
  185. this.numericUpDown1.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
  186. this.numericUpDown1.Value = new decimal(new int[] {
  187. 200,
  188. 0,
  189. 0,
  190. 0});
  191. //
  192. // label4
  193. //
  194. this.label4.AutoSize = true;
  195. this.label4.Location = new System.Drawing.Point(296, 280);
  196. this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
  197. this.label4.Name = "label4";
  198. this.label4.Size = new System.Drawing.Size(17, 12);
  199. this.label4.TabIndex = 13;
  200. this.label4.Text = "‰";
  201. //
  202. // trackBar1
  203. //
  204. this.trackBar1.Location = new System.Drawing.Point(67, 159);
  205. this.trackBar1.Maximum = 200;
  206. this.trackBar1.Minimum = -200;
  207. this.trackBar1.Name = "trackBar1";
  208. this.trackBar1.TrackBarName = "trackBar1";
  209. this.trackBar1.Size = new System.Drawing.Size(200, 30);
  210. this.trackBar1.TabIndex = 14;
  211. this.trackBar1.Value = -50;
  212. //
  213. // label5
  214. //
  215. this.label5.AutoSize = true;
  216. this.label5.Location = new System.Drawing.Point(272, 166);
  217. this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
  218. this.label5.Name = "label5";
  219. this.label5.Size = new System.Drawing.Size(29, 12);
  220. this.label5.TabIndex = 15;
  221. this.label5.Text = "-0.5";
  222. //
  223. // label6
  224. //
  225. this.label6.AutoSize = true;
  226. this.label6.Location = new System.Drawing.Point(272, 202);
  227. this.label6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
  228. this.label6.Name = "label6";
  229. this.label6.Size = new System.Drawing.Size(29, 12);
  230. this.label6.TabIndex = 17;
  231. this.label6.Text = "1.00";
  232. //
  233. // trackBar2
  234. //
  235. this.trackBar2.Location = new System.Drawing.Point(67, 195);
  236. this.trackBar2.Maximum = 999;
  237. this.trackBar2.Minimum = 0;
  238. this.trackBar2.Name = "trackBar2";
  239. this.trackBar2.TrackBarName = "trackBar2";
  240. this.trackBar2.Size = new System.Drawing.Size(200, 30);
  241. this.trackBar2.TabIndex = 16;
  242. this.trackBar2.Value = 100;
  243. //
  244. // label7
  245. //
  246. this.label7.AutoSize = true;
  247. this.label7.Location = new System.Drawing.Point(272, 238);
  248. this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
  249. this.label7.Name = "label7";
  250. this.label7.Size = new System.Drawing.Size(29, 12);
  251. this.label7.TabIndex = 19;
  252. this.label7.Text = "1.00";
  253. this.label7.Visible = false;
  254. //
  255. // trackBar3
  256. //
  257. this.trackBar3.Location = new System.Drawing.Point(67, 230);
  258. this.trackBar3.Maximum = 299;
  259. this.trackBar3.Minimum = 0;
  260. this.trackBar3.Name = "trackBar3";
  261. this.trackBar3.TrackBarName = "trackBar3";
  262. this.trackBar3.Size = new System.Drawing.Size(200, 30);
  263. this.trackBar3.TabIndex = 18;
  264. this.trackBar3.Value = 100;
  265. //
  266. // skipButton
  267. //
  268. this.skipButton.BackColor = System.Drawing.SystemColors.ControlDark;
  269. this.skipButton.BtnSelect = false;
  270. this.skipButton.BtnText = "skip";
  271. this.skipButton.Location = new System.Drawing.Point(275, 77);
  272. this.skipButton.Name = "skipButton";
  273. this.skipButton.Size = new System.Drawing.Size(41, 21);
  274. this.skipButton.TabIndex = 20;
  275. //
  276. // logButton
  277. //
  278. this.logButton.BackColor = System.Drawing.SystemColors.ControlDark;
  279. this.logButton.BtnSelect = false;
  280. this.logButton.BtnText = "log";
  281. this.logButton.Location = new System.Drawing.Point(275, 46);
  282. this.logButton.Name = "logButton";
  283. this.logButton.Size = new System.Drawing.Size(41, 21);
  284. this.logButton.TabIndex = 21;
  285. //
  286. // ucTrackBar1
  287. //
  288. this.ucTrackBar1.DcimalDigits = 0;
  289. this.ucTrackBar1.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(77)))), ((int)(((byte)(59)))));
  290. this.ucTrackBar1.LineWidth = 8F;
  291. this.ucTrackBar1.Location = new System.Drawing.Point(4, 139);
  292. this.ucTrackBar1.MaxValue = 255F;
  293. this.ucTrackBar1.MinValue = 0F;
  294. this.ucTrackBar1.Name = "ucTrackBar1";
  295. this.ucTrackBar1.Size = new System.Drawing.Size(274, 20);
  296. this.ucTrackBar1.TabIndex = 22;
  297. this.ucTrackBar1.Text = "ucTrackBar1";
  298. this.ucTrackBar1.Value1 = 0F;
  299. this.ucTrackBar1.Value2 = 127F;
  300. this.ucTrackBar1.Value3 = 255F;
  301. //
  302. // numericUpDown2
  303. //
  304. this.numericUpDown2.DecimalPlaces = 2;
  305. this.numericUpDown2.Increment = new decimal(new int[] {
  306. 1,
  307. 0,
  308. 0,
  309. 131072});
  310. this.numericUpDown2.Location = new System.Drawing.Point(266, 235);
  311. this.numericUpDown2.Margin = new System.Windows.Forms.Padding(2);
  312. this.numericUpDown2.Maximum = new decimal(new int[] {
  313. 299,
  314. 0,
  315. 0,
  316. 131072});
  317. this.numericUpDown2.Name = "numericUpDown2";
  318. this.numericUpDown2.Size = new System.Drawing.Size(50, 21);
  319. this.numericUpDown2.TabIndex = 23;
  320. this.numericUpDown2.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
  321. this.numericUpDown2.Value = new decimal(new int[] {
  322. 100,
  323. 0,
  324. 0,
  325. 131072});
  326. //
  327. // HistogramDialog
  328. //
  329. this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
  330. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  331. this.ClientSize = new System.Drawing.Size(325, 338);
  332. this.Controls.Add(this.numericUpDown2);
  333. this.Controls.Add(this.ucTrackBar1);
  334. this.Controls.Add(this.logButton);
  335. this.Controls.Add(this.skipButton);
  336. this.Controls.Add(this.label7);
  337. this.Controls.Add(this.trackBar3);
  338. this.Controls.Add(this.label6);
  339. this.Controls.Add(this.trackBar2);
  340. this.Controls.Add(this.label5);
  341. this.Controls.Add(this.trackBar1);
  342. this.Controls.Add(this.label4);
  343. this.Controls.Add(this.numericUpDown1);
  344. this.Controls.Add(this.label3);
  345. this.Controls.Add(this.label2);
  346. this.Controls.Add(this.label1);
  347. this.Controls.Add(this.button5);
  348. this.Controls.Add(this.button4);
  349. this.Controls.Add(this.button3);
  350. this.Controls.Add(this.button2);
  351. this.Controls.Add(this.pictureBox1);
  352. this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
  353. this.Margin = new System.Windows.Forms.Padding(6);
  354. this.Name = "HistogramDialog";
  355. this.Text = "直方图";
  356. this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.HistogramDialog_FormClosing);
  357. this.Controls.SetChildIndex(this.pictureBox1, 0);
  358. this.Controls.SetChildIndex(this.button2, 0);
  359. this.Controls.SetChildIndex(this.button3, 0);
  360. this.Controls.SetChildIndex(this.button4, 0);
  361. this.Controls.SetChildIndex(this.button5, 0);
  362. this.Controls.SetChildIndex(this.label1, 0);
  363. this.Controls.SetChildIndex(this.label2, 0);
  364. this.Controls.SetChildIndex(this.label3, 0);
  365. this.Controls.SetChildIndex(this.numericUpDown1, 0);
  366. this.Controls.SetChildIndex(this.label4, 0);
  367. this.Controls.SetChildIndex(this.trackBar1, 0);
  368. this.Controls.SetChildIndex(this.label5, 0);
  369. this.Controls.SetChildIndex(this.trackBar2, 0);
  370. this.Controls.SetChildIndex(this.label6, 0);
  371. this.Controls.SetChildIndex(this.trackBar3, 0);
  372. this.Controls.SetChildIndex(this.label7, 0);
  373. this.Controls.SetChildIndex(this.skipButton, 0);
  374. this.Controls.SetChildIndex(this.logButton, 0);
  375. this.Controls.SetChildIndex(this.ucTrackBar1, 0);
  376. this.Controls.SetChildIndex(this.numericUpDown2, 0);
  377. ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
  378. ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
  379. ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndInit();
  380. this.ResumeLayout(false);
  381. this.PerformLayout();
  382. }
  383. #endregion
  384. public HistogramDialog(AppWorkspace AppWorkspace)
  385. {
  386. this.AppWorkspace = AppWorkspace;
  387. InitializeComponent();
  388. InitializeLanguageText();
  389. this.Text = PdnResources.GetString("Menu.Tools.Histogram.Text");
  390. if (this.AppWorkspace.ActiveDocumentWorkspace != null)
  391. {
  392. updateHistImg(oldHists);
  393. updateHistogramRect(false);
  394. }
  395. if(this.AppWorkspace != null)
  396. this.AppWorkspace.ActiveDocumentWorkspaceChanged += new EventHandler(ButtonFocus);
  397. AddAllEvent();
  398. }
  399. /// <summary>
  400. /// 更改按钮焦点
  401. /// </summary>
  402. /// <param name="dis">按钮区分</param>
  403. public void ButtonFocus(object sender, EventArgs e)
  404. {
  405. if(AppWorkspace != null && AppWorkspace.ActiveDocumentWorkspace != null)
  406. {
  407. // 最佳
  408. if (AppWorkspace.ActiveDocumentWorkspace.buttonType == 0)
  409. {
  410. this.button2.Focus();
  411. }
  412. // 最大最小
  413. if (AppWorkspace.ActiveDocumentWorkspace.buttonType == 1)
  414. {
  415. this.button3.Focus();
  416. }
  417. // 伽马45
  418. if (AppWorkspace.ActiveDocumentWorkspace.buttonType == 2)
  419. {
  420. this.button4.Focus();
  421. }
  422. // 原始
  423. if (AppWorkspace.ActiveDocumentWorkspace.buttonType == 3)
  424. {
  425. this.button5.Focus();
  426. }
  427. }
  428. }
  429. /// <summary>
  430. /// 重置Mat
  431. /// </summary>
  432. public void ResetMat()
  433. {
  434. if (this.AppWorkspace.ActiveDocumentWorkspace == null || this.AppWorkspace.ActiveDocumentWorkspace.CompositionSurface == null)
  435. {
  436. this.Visible = false;
  437. isGray = true;
  438. return;
  439. }
  440. this.RemoveAllEvent();
  441. Mat[] mats = Cv2.Split(this.AppWorkspace.ActiveDocumentWorkspace.BoxMat);
  442. Mat[] mats0 = new Mat[] { mats[0] };
  443. Mat[] mats1 = new Mat[] { mats[1] };
  444. Mat[] mats2 = new Mat[] { mats[2] };
  445. int[] channels0 = new int[] { 0 };
  446. int[] channels1 = new int[] { 0 };
  447. int[] channels2 = new int[] { 0 };
  448. int[] histsize = new int[] { 256 };
  449. Rangef[] range = new Rangef[1];
  450. range[0] = new Rangef(0.0F, 256.0F);
  451. Mat mask = new Mat();
  452. Cv2.CalcHist(mats0, channels0, mask, oldHists[0], 1, histsize, range);
  453. Cv2.CalcHist(mats1, channels1, mask, oldHists[1], 1, histsize, range);
  454. Cv2.CalcHist(mats2, channels2, mask, oldHists[2], 1, histsize, range);
  455. if (this.AppWorkspace.ActiveDocumentWorkspace != null)
  456. {
  457. //获取gamma值
  458. double gamma = this.AppWorkspace.ActiveDocumentWorkspace.HistogramGamma;
  459. this.trackBar3.Value = Math.Min(299, (int)(gamma * 100));
  460. numericUpDown2.Value = decimal.Parse(gamma.ToString("f2"));
  461. //获取对比度
  462. double alpha = this.AppWorkspace.ActiveDocumentWorkspace.HistogramAlpha;
  463. //获取亮度
  464. double beta = this.AppWorkspace.ActiveDocumentWorkspace.HistogramBeta;
  465. //计算对比度
  466. label6.Text = alpha.ToString("f2");
  467. trackBar2.Value = Math.Min(trackBar2.Maximum, (int)(double.Parse(label6.Text) * 100));
  468. //计算亮度
  469. if (beta != double.Parse(label5.Text))
  470. {
  471. label5.Text = beta.ToString("f2");
  472. trackBar1.Value = (int)(double.Parse(label5.Text) * 100);
  473. }
  474. this.numericUpDown1.Value = new decimal(new int[] { (int)this.AppWorkspace.ActiveDocumentWorkspace.HistogramPercent, 0, 0, 0});
  475. skipButton.BtnSelect = this.AppWorkspace.ActiveDocumentWorkspace.HistogramSkipEnabled;
  476. logButton.BtnSelect = this.AppWorkspace.ActiveDocumentWorkspace.HistogramLogEnabled;
  477. }
  478. this.updateHistImg(null);
  479. this.updateHistogramRect(true);
  480. this.AddAllEvent();
  481. }
  482. /// <summary>
  483. /// 绘制直方图
  484. /// </summary>
  485. /// <param name="hist"></param>
  486. /// <returns></returns>
  487. private unsafe void updateHistImg(Mat[] hists)
  488. {
  489. if (this.AppWorkspace.ActiveDocumentWorkspace == null)
  490. {
  491. return;
  492. }
  493. //分割图像
  494. //Mat[] mats = Cv2.Split(this.AppWorkspace.ActiveDocumentWorkspace.OldMat);
  495. Mat[] mats = Cv2.Split(this.AppWorkspace.ActiveDocumentWorkspace.BoxMat);
  496. Mat[] mats0 = new Mat[] { mats[0] };
  497. Mat[] mats1 = new Mat[] { mats[1] };
  498. Mat[] mats2 = new Mat[] { mats[2] };
  499. //判断是否灰度
  500. isGray = ((mats[0].Sum())[0] == (mats[1].Sum())[0] && (mats[1].Sum())[0] == (mats[2].Sum())[0]);
  501. if (hists == null)
  502. {
  503. hists = new Mat[] { new Mat(), new Mat(), new Mat() };//一个矩阵数组,用来接收直方图,记得全部初始化
  504. int[] channels0 = new int[] { 0 };//一个通道,初始化为通道0,这些东西可以共用设置一个就行
  505. int[] channels1 = new int[] { 0 };
  506. int[] channels2 = new int[] { 0 };
  507. int[] histsize = new int[] { 256 };//一个通道,初始化为256箱子
  508. Rangef[] range = new Rangef[1];//一个通道,范围
  509. range[0] = new Rangef(0.0F, 256.0F);
  510. Mat mask = new Mat();//不做掩码
  511. Cv2.CalcHist(mats0, channels0, mask, hists[0], 1, histsize, range);//对被拆分的图片单独进行计算
  512. Cv2.CalcHist(mats1, channels1, mask, hists[1], 1, histsize, range);//对被拆分的图片单独进行计算
  513. Cv2.CalcHist(mats2, channels2, mask, hists[2], 1, histsize, range);//对被拆分的图片单独进行计算
  514. if (logButton.BtnSelect)
  515. {
  516. //取对数
  517. for (int j = 0; j < hists.Length; j++)
  518. {
  519. List<float> ProbPixel = new List<float>();
  520. for (int i = 0; i < hists[j].Rows; i++)
  521. {
  522. if (((float*)hists[j].Ptr(0))[i] == 0)
  523. {
  524. ((float*)hists[j].Ptr(0))[i] = ((float*)hists[j].Ptr(0))[i];
  525. ProbPixel.Add(0);
  526. }
  527. else
  528. {
  529. ((float*)hists[j].Ptr(0))[i] = (float)Math.Log10(((float*)hists[j].Ptr(0))[i]/* + 9*/);
  530. ProbPixel.Add(1);
  531. }
  532. }
  533. double max1jVal = 0;
  534. double min1jVal = 0;
  535. //找到直方图中的最大值和最小值
  536. Cv2.MinMaxLoc(hists[j], out min1jVal, out max1jVal);
  537. if (min1jVal >= max1jVal)
  538. {
  539. continue;
  540. }
  541. //归一化到0~255,并根据AxioVision添加偏置值
  542. for (int i = 0; i < hists[j].Rows; i++)
  543. {
  544. ((float*)hists[j].Ptr(0))[i] = (float)((((float*)hists[j].Ptr(0))[i] - 0) * 255.0 / (max1jVal - 0)) + (float)(min1jVal > 0 ? (ProbPixel[i] * min1jVal * 255.0 / max1jVal) : ProbPixel[i] * 5);
  545. }
  546. }
  547. }
  548. if (skipButton.BtnSelect)
  549. {
  550. //去掉黑色部分 和 白色部分
  551. for (int j = 0; j < hists.Length; j++)
  552. {
  553. ((float*)hists[j].Ptr(0))[0] = 0;
  554. ((float*)hists[j].Ptr(0))[255] = 0;
  555. }
  556. }
  557. }
  558. double max2Val = 0;
  559. double max1Val = 0;
  560. double max0Val = 0;
  561. double minVal = 0;
  562. //为了更好显示直方图细节,使用4倍尺寸绘制直方图
  563. int histSize = hists[0].Rows * 4;
  564. Mat histImg = new Mat(histSize, histSize, MatType.CV_8UC3, new Scalar(255, 255, 255));
  565. //找到直方图中的最大值和最小值
  566. Cv2.MinMaxLoc(hists[2], out minVal, out max2Val);
  567. Cv2.MinMaxLoc(hists[1], out minVal, out max1Val);
  568. Cv2.MinMaxLoc(hists[0], out minVal, out max0Val);
  569. double maxVal = Math.Max(max2Val, Math.Max(max0Val, max1Val));
  570. if (maxVal < 1)
  571. return;
  572. // 设置最大峰值为图像高度的90%
  573. double hpt = 0.9 * histSize;
  574. //灰度图的显示直方图较为简单,显示一个通道即可
  575. if (isGray)
  576. {
  577. Mat hist = hists[0];
  578. int lastY2 = histSize - 1;
  579. for (int h = 0; h < hists[0].Rows; h++)
  580. {
  581. int intensity = (int)(hist.At<float>(h) * hpt / maxVal);
  582. int lastY1 = lastY2;
  583. lastY2 = histSize - intensity - 1 - (hist.At<float>(h) > 0 ? 4 : 0);
  584. if (lastY2 < lastY1)
  585. {
  586. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4, lastY1), new OpenCvSharp.Point(h * 4, Math.Min(lastY2, lastY1 - 2)), new Scalar(0, 0, 0, 255), 2, LineTypes.Link4);
  587. }
  588. else
  589. {
  590. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4, lastY1), new OpenCvSharp.Point(h * 4, Math.Max(lastY2, lastY1 + 2)), new Scalar(0, 0, 0, 255), 2, LineTypes.Link4);
  591. }
  592. }
  593. }
  594. //彩度图显示BGR三个通道的直方图
  595. else
  596. {
  597. int lineWidth = 2;
  598. for (int j = hists.Length - 1; j >= 0; j--)
  599. {
  600. Mat hist = hists[j];
  601. int lastY2 = histSize - 1;
  602. for (int h = 0; h < hists[0].Rows; h++)
  603. {
  604. int intensity = (int)(hist.At<float>(h) * hpt / maxVal);
  605. int lastY1 = lastY2;
  606. lastY2 = histSize - intensity - 1 - (hist.At<float>(h) > 0 ? 4 : 0);
  607. if (h > 0)
  608. {
  609. //显示0.5位置的直方图,这样与AxioVision效果更加近似
  610. int lasty12 = (lastY1 + lastY2) / 2;
  611. if (lasty12 < lastY1)
  612. {
  613. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4 - 2, lastY1), new OpenCvSharp.Point(h * 4 - 2, Math.Min(lasty12, lastY1 - 2)), color[j], lineWidth, LineTypes.Link4);
  614. }
  615. else
  616. {
  617. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4 - 2, lastY1), new OpenCvSharp.Point(h * 4 - 2, Math.Max(lasty12, lastY1 + 2)), color[j], lineWidth, LineTypes.Link4/*AntiAlias*/);
  618. }
  619. if (lastY2 < lasty12)
  620. {
  621. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4, lasty12), new OpenCvSharp.Point(h * 4, Math.Min(lastY2, lasty12 - 2)), color[j], lineWidth, LineTypes.Link4);
  622. }
  623. else
  624. {
  625. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4, lasty12), new OpenCvSharp.Point(h * 4, Math.Max(lastY2, lasty12 + 2)), color[j], lineWidth, LineTypes.Link4/*AntiAlias*/);
  626. }
  627. }
  628. else
  629. {
  630. //灰度值为0的线的绘制
  631. if (lastY2 < lastY1)
  632. {
  633. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4, lastY1), new OpenCvSharp.Point(h * 4, Math.Min(lastY2, lastY1 - 2)), color[j], lineWidth, LineTypes.Link4);
  634. }
  635. else
  636. {
  637. Cv2.Line(histImg, new OpenCvSharp.Point(h * 4, lastY1), new OpenCvSharp.Point(h * 4, Math.Max(lastY2, lastY1 + 2)), color[j], lineWidth, LineTypes.Link4/*AntiAlias*/);
  638. }
  639. }
  640. }
  641. }
  642. }
  643. this.pictureBox1.BackgroundImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(histImg);
  644. }
  645. /// <summary>
  646. /// 将拟合点绘制到空白图上
  647. /// </summary>
  648. /// <param name="key_point">拟合点</param>
  649. /// <param name="n">拟合矩阵的数量</param>
  650. /// <param name="A">空白图</param>
  651. /// <returns></returns>
  652. private unsafe bool polynomial_curve_fit(OpenCvSharp.Point[] key_point, int n, Mat A)
  653. {
  654. int N = key_point.Length;
  655. //构造矩阵X
  656. Mat X = new Mat(n + 1, n + 1, MatType.CV_64FC1, new Scalar(0));
  657. for (int i = 0; i < n + 1; i++)
  658. {
  659. for (int j = 0; j < n + 1; j++)
  660. {
  661. ((double*)X.Ptr(i))[j] = 0;
  662. for (int k = 0; k < N; k++)
  663. {
  664. ((double*)X.Ptr(i))[j] = X.At<double>(i, j) + (double)Math.Pow(key_point[k].X, i + j);
  665. }
  666. }
  667. }
  668. //构造矩阵Y
  669. Mat Y = new Mat(n + 1, 1, MatType.CV_64FC1, new Scalar(0));
  670. for (int i = 0; i < n + 1; i++)
  671. {
  672. ((double*)Y.Ptr(i))[0] = 0;//111
  673. for (int k = 0; k < N; k++)
  674. {
  675. ((double*)Y.Ptr(i))[0] = Y.At<double>(i, 0) + (double)(Math.Pow(key_point[k].X, i) * key_point[k].Y);
  676. }
  677. }
  678. //求解矩阵A
  679. Cv2.Solve(X, Y, A, DecompTypes.LU);
  680. return true;
  681. }
  682. /// <summary>
  683. /// 通过颜色通道去除像素点的千分比计算有效阈值
  684. /// </summary>
  685. /// <param name="hists"></param>
  686. /// <param name="percentValue"></param>
  687. /// <returns></returns>
  688. private OpenCvSharp.Point getStartIndex(Mat mat, Mat[] hists, float percentValue)
  689. {
  690. //灰度化图片取第一通道
  691. Mat histGray = hists[0];
  692. //彩色图片取灰度化后的通道
  693. if (!isGray)
  694. {
  695. OpenCvSharp.Point startIndex = new OpenCvSharp.Point(0, histGray.Rows);
  696. //计算三次
  697. OpenCvSharp.Point startIndex0 = this.getStartRange(mat, hists[0], percentValue);
  698. OpenCvSharp.Point startIndex1 = this.getStartRange(mat, hists[1], percentValue);
  699. OpenCvSharp.Point startIndex2 = this.getStartRange(mat, hists[2], percentValue);
  700. startIndex.X = Math.Min(startIndex0.X, Math.Min(startIndex1.X, startIndex2.X));
  701. startIndex.Y = Math.Max(startIndex0.Y, Math.Max(startIndex1.Y, startIndex2.Y));
  702. startIndex.Y = Math.Min(255 - 1, startIndex.Y);
  703. startIndex.X = Math.Max(startIndex.X, 1);
  704. startIndex.Y = Math.Max(startIndex.X + 1, startIndex.Y);
  705. return startIndex;
  706. }
  707. return this.getStartRange(mat, histGray, percentValue);
  708. }
  709. private OpenCvSharp.Point getStartRange(Mat mat, Mat histGray, float percentValue)
  710. {
  711. if (this.AppWorkspace.ActiveDocumentWorkspace == null)
  712. {
  713. return new OpenCvSharp.Point(1, 254); ;
  714. }
  715. //计算灰度分布密度
  716. //float totalPoints = this.AppWorkspace.ActiveDocumentWorkspace.OldMat.Cols * this.AppWorkspace.ActiveDocumentWorkspace.OldMat.Rows;
  717. float totalPoints = mat.Cols * mat.Rows;
  718. OpenCvSharp.Point startIndex = new OpenCvSharp.Point(0, histGray.Rows);
  719. bool foundStartTag = false;
  720. bool foundEndTag = false;
  721. //根据累计直方图分布计算左右阈值
  722. float equalizeHists = 0;
  723. for (int i = 0; i < histGray.Rows; ++i)
  724. {
  725. equalizeHists += ((float)(histGray.At<float>(i) / (totalPoints * 1.0))) * 1000;
  726. if (!foundStartTag && equalizeHists > percentValue)
  727. {
  728. foundStartTag = true;
  729. startIndex.X = i;
  730. }
  731. else if (equalizeHists >= 1000 - percentValue)
  732. {
  733. foundEndTag = true;
  734. startIndex.Y = i;
  735. }
  736. if (foundStartTag && foundEndTag)
  737. break;
  738. }
  739. startIndex.Y = Math.Min(255 - 1, startIndex.Y);
  740. startIndex.X = Math.Max(startIndex.X, 1);
  741. startIndex.Y = Math.Max(startIndex.X + 1, startIndex.Y);
  742. return startIndex;
  743. }
  744. /// <summary>
  745. /// 更新直方图特征曲线
  746. /// </summary>
  747. /// <param name="updateThreePoints">是否需要更新三个控制点的位置</param>
  748. private void updateHistogramRect(bool updateThreePoints)
  749. {
  750. //为了更好显示直方图细节,使用4倍尺寸绘制直方图
  751. int histSize = 256 * 4;
  752. //创建用于绘制的深蓝色背景图像
  753. Mat image = new Mat(histSize, histSize, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  754. //输入拟合点
  755. List<OpenCvSharp.Point> points = new List<OpenCvSharp.Point>();
  756. //根据亮度和对比度计算左右阈值
  757. int grayMin = (int)(0 - (256.0 / (double.Parse(label6.Text) == 0 ? 0.01 : double.Parse(label6.Text)) + double.Parse(label5.Text) * 510.0) / 2.0);
  758. int grayMax = (int)((256.0 / (double.Parse(label6.Text) == 0 ? 0.01 : double.Parse(label6.Text)) - double.Parse(label5.Text) * 510.0) / 2.0);
  759. if (grayMin >= grayMax)
  760. {
  761. return;
  762. }
  763. if (updateThreePoints)
  764. {
  765. ucTrackBar1.Value1 = grayMin;
  766. ucTrackBar1.Value3 = grayMax;
  767. }
  768. //gamma运算,gamma值根据AxioVision对比 取最小值0.01进行计算
  769. double gamma = Math.Max(0.01, /*double.Parse(label7.Text)*/(double)numericUpDown2.Value);
  770. //计算Value2
  771. ucTrackBar1.Value2 = (float)Math.Max(grayMin, Math.Min(grayMax, Math.Pow(0.5, 1.0 / gamma) * (grayMax - grayMin) + grayMin));
  772. ucTrackBar1.Refresh();
  773. int lastY2 = histSize + 0;// histSize - 1;
  774. for (int h = 0; h <= 256; h++)
  775. {
  776. if (h < grayMin)
  777. {
  778. points.Add(new OpenCvSharp.Point(h * 4, lastY2));
  779. continue;
  780. }
  781. else if (h > grayMax)
  782. {
  783. lastY2 = -1;// 0;
  784. points.Add(new OpenCvSharp.Point(h * 4, lastY2));
  785. continue;
  786. }
  787. int lastY1 = (int)Math.Round((1.0 - Math.Pow((h - grayMin) * 1.0 / (grayMax - grayMin), gamma)) * (histSize + 1/*histSize - 1*/)) - 1;
  788. lastY1 = Math.Min(lastY2, Math.Max(0, lastY1));
  789. if (lastY2 == lastY1)
  790. {
  791. if (h == 0 || h == 256)
  792. {
  793. points.Add(new OpenCvSharp.Point(h * 4, lastY1));
  794. }
  795. }
  796. else
  797. {
  798. points.Add(new OpenCvSharp.Point(h * 4, lastY1));
  799. lastY2 = lastY1;
  800. }
  801. }
  802. lastY2 = histSize + 0;
  803. //将第一个点的位置设置最底部,保证曲线平滑性
  804. List<List<OpenCvSharp.Point>> pointsIn = new List<List<OpenCvSharp.Point>>() { points };
  805. //绘制折线
  806. Cv2.Polylines(image, pointsIn, false, new Scalar(0, 0, 0, 255), 4, LineTypes.Link8, 0);
  807. Mat A = new Mat(3 + 1, 1, MatType.CV_64FC1, new Scalar(0));
  808. polynomial_curve_fit(points.ToArray(), 3, A);
  809. List<OpenCvSharp.Point> points_fitted = new List<OpenCvSharp.Point>();
  810. List<double> dataFitted = new List<double>();
  811. dataFitted.Add(A.At<double>(0, 0));
  812. dataFitted.Add(A.At<double>(1, 0));
  813. dataFitted.Add(A.At<double>(2, 0));
  814. dataFitted.Add(A.At<double>(3, 0));
  815. for (int x = 0; x < histSize + 1; x++)
  816. {
  817. if (x < grayMin * 4)
  818. {
  819. points_fitted.Add(new OpenCvSharp.Point(x, lastY2));
  820. continue;
  821. }
  822. else if (x > grayMax * 4)
  823. {
  824. lastY2 = -1;
  825. points_fitted.Add(new OpenCvSharp.Point(x, lastY2));
  826. continue;
  827. }
  828. double y = A.At<double>(0, 0) + A.At<double>(1, 0) * x + A.At<double>(2, 0) * Math.Pow(x, 2) + A.At<double>(3, 0) * Math.Pow(x, 3);
  829. points_fitted.Add(new OpenCvSharp.Point(x, y));
  830. }
  831. ////绘制折线
  832. this.pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(image);
  833. }
  834. /// <summary>
  835. /// 根据亮度、对比度、gamma对图片进行处理
  836. /// https://blog.csdn.net/kuweicai/article/details/78953017
  837. /// https://blog.csdn.net/ren365880/article/details/103875302
  838. /// https://zhuanlan.zhihu.com/p/92945623
  839. /// </summary>
  840. private unsafe void scrollMethod()
  841. {
  842. if (this.AppWorkspace.ActiveDocumentWorkspace == null)
  843. {
  844. return;
  845. }
  846. Mat[] mats = Cv2.Split(this.AppWorkspace.ActiveDocumentWorkspace.OldMat);
  847. //根据亮度和对比度计算左右阈值
  848. int grayMin = (int)(0 - (256.0 / (double.Parse(label6.Text) == 0 ? 0.01 : double.Parse(label6.Text)) + double.Parse(label5.Text) * 510.0) / 2.0);
  849. int grayMax = (int)((256.0 / (double.Parse(label6.Text) == 0 ? 0.01 : double.Parse(label6.Text)) - double.Parse(label5.Text) * 510.0) / 2.0);
  850. if (grayMin >= grayMax)
  851. {
  852. return;
  853. }
  854. Mat dst = new Mat();
  855. //如果是灰度化图片,则只需计算一个通道。对灰度值进行映射,BGR根据左右阈值做缩放操作
  856. if (isGray)
  857. {
  858. Cv2.Min(mats[0], new Mat(mats[0].Rows, mats[0].Cols, MatType.CV_8UC1, new Scalar(grayMax)), dst);
  859. Cv2.Max(dst, new Mat(mats[0].Rows, mats[0].Cols, MatType.CV_8UC1, new Scalar(grayMin)), dst);
  860. Cv2.Normalize(dst, dst, 0, 255, NormTypes.MinMax);
  861. }
  862. else
  863. {
  864. for (int j = 0; j < 3; j++)
  865. {
  866. Cv2.Min(mats[j], new Mat(mats[j].Rows, mats[j].Cols, MatType.CV_8UC1, new Scalar(grayMax)), mats[j]);
  867. Cv2.Max(mats[j], new Mat(mats[j].Rows, mats[j].Cols, MatType.CV_8UC1, new Scalar(grayMin)), mats[j]);
  868. }
  869. Cv2.Merge(mats, dst);
  870. Cv2.Normalize(dst, dst, 0, 255, NormTypes.MinMax);
  871. }
  872. /*Mat dst = this.AppWorkspace.ActiveDocumentWorkspace.OldMat;
  873. if (dst.Channels() > 3) dst = dst.CvtColor(ColorConversionCodes.BGRA2BGR);
  874. dst.ConvertTo(dst, dst.Type(), double.Parse(label6.Text), double.Parse(label5.Text));*/
  875. /*//灰度归一化
  876. dst.ConvertTo(dst, MatType.CV_64F, 1.0 / 255, 0);
  877. //gamma运算,gamma值根据AxioVision对比 取最小值0.01进行计算
  878. Cv2.Pow(dst, Math.Max(0.01, (double)numericUpDown2.Value), dst);
  879. dst.ConvertTo(dst, MatType.CV_8U, 255, 0);*/
  880. for (int i = 0; i < 256; ++i)
  881. lookUpTable.Set<byte>(0, i, (byte)(Math.Pow(i / 255.0, (double)numericUpDown2.Value) * 255.0));
  882. Cv2.LUT(dst, lookUpTable, dst);
  883. Document document = Document.FromImageMatForHistogram(dst, this.AppWorkspace.ActiveDocumentWorkspace.CompositionSurface);
  884. this.AppWorkspace.ActiveDocumentWorkspace.setDoc(document, false);
  885. this.AppWorkspace.ActiveDocumentWorkspace.Refresh();
  886. }
  887. private void HistogramDialog_FormClosing(object sender, FormClosingEventArgs e)
  888. {
  889. this.AppWorkspace.toolBar.RefreshBtnSelect(false, "Histogram");
  890. this.AppWorkspace.toolsPanel.RefreshBtnSelect(false, "Histogram");
  891. }
  892. /// <summary>
  893. /// 移除事件
  894. /// </summary>
  895. private void RemoveAllEvent()
  896. {
  897. /*this.button2.Click -= new System.EventHandler(this.button2_Click);
  898. this.button3.Click -= new System.EventHandler(this.button3_Click);
  899. this.button4.Click -= new System.EventHandler(this.button4_Click);
  900. this.button5.Click -= new System.EventHandler(this.button5_Click);
  901. this.numericUpDown1.ValueChanged -= new System.EventHandler(this.numericUpDown1_ValueChanged);
  902. this.label5.TextChanged -= new System.EventHandler(this.label5_Changed);
  903. this.label6.TextChanged -= new System.EventHandler(this.label6_Changed);
  904. this.label7.TextChanged -= new System.EventHandler(this.label7_Changed);
  905. this.skipButton.Click -= new System.EventHandler(this.skipButton_Click);
  906. this.logButton.Click -= new System.EventHandler(this.logButton_Click);
  907. this.ucTrackBar1.Value1Changed -= new System.EventHandler(this.ucTrackBar1_Value1Changed);
  908. this.ucTrackBar1.Value2Changed -= new System.EventHandler(this.ucTrackBar1_Value2Changed);
  909. this.ucTrackBar1.Value3Changed -= new System.EventHandler(this.ucTrackBar1_Value3Changed);
  910. this.numericUpDown2.ValueChanged -= new System.EventHandler(this.numericUpDown2_ValueChanged);*/
  911. this.button2.Click -= new System.EventHandler(this.EventIncident);
  912. this.button3.Click -= new System.EventHandler(this.EventIncident);
  913. this.button4.Click -= new System.EventHandler(this.EventIncident);
  914. this.button5.Click -= new System.EventHandler(this.EventIncident);
  915. this.numericUpDown1.ValueChanged -= new System.EventHandler(this.EventIncident);
  916. this.label5.TextChanged -= new System.EventHandler(this.EventIncident);
  917. this.label6.TextChanged -= new System.EventHandler(this.EventIncident);
  918. this.label7.TextChanged -= new System.EventHandler(this.EventIncident);
  919. this.skipButton.Click -= new System.EventHandler(this.EventIncident);
  920. this.logButton.Click -= new System.EventHandler(this.EventIncident);
  921. this.numericUpDown2.ValueChanged -= new System.EventHandler(this.EventIncident);
  922. this.ucTrackBar1.Value1Changed -= new System.EventHandler(this.ucTrackBar1_Value1Changed);
  923. this.ucTrackBar1.Value2Changed -= new System.EventHandler(this.ucTrackBar1_Value2Changed);
  924. this.ucTrackBar1.Value3Changed -= new System.EventHandler(this.ucTrackBar1_Value3Changed);
  925. this.ucTrackBar1.ValueMouseUp -= new System.EventHandler(this.EventIncident);
  926. this.trackBar1.TrackBarScroll -= new System.EventHandler(this.trackBar1_Scroll);
  927. this.trackBar2.TrackBarScroll -= new System.EventHandler(this.trackBar2_Scroll);
  928. this.trackBar3.TrackBarScroll -= new System.EventHandler(this.trackBar3_Scroll);
  929. this.trackBar1.TrackBarMouseUp -= new System.EventHandler(this.EventIncident);
  930. this.trackBar2.TrackBarMouseUp -= new System.EventHandler(this.EventIncident);
  931. this.trackBar3.TrackBarMouseUp -= new System.EventHandler(this.EventIncident);
  932. }
  933. /// <summary>
  934. /// 添加事件
  935. /// </summary>
  936. private void AddAllEvent()
  937. {
  938. /*this.button2.Click += new System.EventHandler(this.button2_Click);
  939. this.button3.Click += new System.EventHandler(this.button3_Click);
  940. this.button4.Click += new System.EventHandler(this.button4_Click);
  941. this.button5.Click += new System.EventHandler(this.button5_Click);
  942. this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged);
  943. this.label5.TextChanged += new System.EventHandler(this.label5_Changed);
  944. this.label6.TextChanged += new System.EventHandler(this.label6_Changed);
  945. this.label7.TextChanged += new System.EventHandler(this.label7_Changed);
  946. this.skipButton.Click += new System.EventHandler(this.skipButton_Click);
  947. this.logButton.Click += new System.EventHandler(this.logButton_Click);
  948. this.ucTrackBar1.Value1Changed += new System.EventHandler(this.ucTrackBar1_Value1Changed);
  949. this.ucTrackBar1.Value2Changed += new System.EventHandler(this.ucTrackBar1_Value2Changed);
  950. this.ucTrackBar1.Value3Changed += new System.EventHandler(this.ucTrackBar1_Value3Changed);
  951. this.numericUpDown2.ValueChanged += new System.EventHandler(this.numericUpDown2_ValueChanged);*/
  952. this.button2.Click += new System.EventHandler(this.EventIncident);
  953. this.button3.Click += new System.EventHandler(this.EventIncident);
  954. this.button4.Click += new System.EventHandler(this.EventIncident);
  955. this.button5.Click += new System.EventHandler(this.EventIncident);
  956. this.numericUpDown1.ValueChanged += new System.EventHandler(this.EventIncident);
  957. this.label5.TextChanged += new System.EventHandler(this.EventIncident);
  958. this.label6.TextChanged += new System.EventHandler(this.EventIncident);
  959. this.label7.TextChanged += new System.EventHandler(this.EventIncident);
  960. this.skipButton.Click += new System.EventHandler(this.EventIncident);
  961. this.logButton.Click += new System.EventHandler(this.EventIncident);
  962. this.numericUpDown2.ValueChanged += new System.EventHandler(this.EventIncident);
  963. this.ucTrackBar1.Value1Changed += new System.EventHandler(this.ucTrackBar1_Value1Changed);
  964. this.ucTrackBar1.Value2Changed += new System.EventHandler(this.ucTrackBar1_Value2Changed);
  965. this.ucTrackBar1.Value3Changed += new System.EventHandler(this.ucTrackBar1_Value3Changed);
  966. this.ucTrackBar1.ValueMouseUp += new System.EventHandler(this.EventIncident);
  967. this.trackBar1.TrackBarScroll += new System.EventHandler(this.trackBar1_Scroll);
  968. this.trackBar2.TrackBarScroll += new System.EventHandler(this.trackBar2_Scroll);
  969. this.trackBar3.TrackBarScroll += new System.EventHandler(this.trackBar3_Scroll);
  970. this.trackBar1.TrackBarMouseUp += new System.EventHandler(this.EventIncident);
  971. this.trackBar2.TrackBarMouseUp += new System.EventHandler(this.EventIncident);
  972. this.trackBar3.TrackBarMouseUp += new System.EventHandler(this.EventIncident);
  973. }
  974. /// <summary>
  975. /// 所有事件的统一入口
  976. /// </summary>
  977. /// <param name="sender"></param>
  978. /// <param name="e"></param>
  979. public void EventIncident(object sender, EventArgs e)
  980. {
  981. if (this.AppWorkspace.ActiveDocumentWorkspace == null)
  982. {
  983. MessageBox.Show(PdnResources.GetString("Menu.Pleaseopenthepicture.Text"));
  984. return;
  985. }
  986. //移除事件
  987. this.RemoveAllEvent();
  988. string controlName = ((Control)sender).Name;
  989. switch(controlName)
  990. {
  991. case "button2":
  992. this.BestButtonMethod();
  993. this.EventIncidentBranch(null);
  994. this.SaveParameter();
  995. this.AppWorkspace.MaxMinBest(true, false, false, false);
  996. break;
  997. case "button3":
  998. this.MaxMinButtonMethod();
  999. this.EventIncidentBranch(null);
  1000. this.SaveParameter();
  1001. this.AppWorkspace.MaxMinBest(false, true, false, false);
  1002. break;
  1003. case "button4":
  1004. this.Gamma45ButtonMethod();
  1005. this.EventIncidentBranch(null);
  1006. this.SaveParameter();
  1007. this.AppWorkspace.MaxMinBest(false, false, false, true);
  1008. break;
  1009. case "button5":
  1010. this.OriginButtonMethod();
  1011. Document document = Document.FromImageMat(this.AppWorkspace.ActiveDocumentWorkspace.CompositionSurface.BackUpMat);
  1012. this.AppWorkspace.ActiveDocumentWorkspace.setDoc(document, false);
  1013. this.AppWorkspace.ActiveDocumentWorkspace.Refresh();
  1014. this.EventIncidentBranch(null, false);
  1015. this.SaveParameter();
  1016. this.AppWorkspace.MaxMinBest(false, false, true, false);
  1017. break;
  1018. case "skipButton":
  1019. this.skipButton.BtnSelect = !skipButton.BtnSelect;
  1020. this.AppWorkspace.ActiveDocumentWorkspace.HistogramSkipEnabled = skipButton.BtnSelect;
  1021. this.updateHistImg(null);
  1022. break;
  1023. case "logButton":
  1024. this.logButton.BtnSelect = !logButton.BtnSelect;
  1025. this.AppWorkspace.ActiveDocumentWorkspace.HistogramLogEnabled = logButton.BtnSelect;
  1026. this.updateHistImg(null);
  1027. break;
  1028. case "ucTrackBar1":
  1029. case "ucTrackBar2":
  1030. case "ucTrackBar3":
  1031. case "numericUpDown1":
  1032. case "trackBar1":
  1033. case "label5":
  1034. case "label6":
  1035. case "trackBar2":
  1036. case "label7":
  1037. case "trackBar3":
  1038. case "numericUpDown2":
  1039. case "triangleButtonSubtract":
  1040. case "triangleButtonPlus":
  1041. EventIncidentBranch(controlName);
  1042. break;
  1043. default:
  1044. break;
  1045. }
  1046. //添加事件
  1047. this.AddAllEvent();
  1048. }
  1049. public void SaveParameter()
  1050. {
  1051. if (this.AppWorkspace.ActiveDocumentWorkspace != null)
  1052. {
  1053. this.AppWorkspace.ActiveDocumentWorkspace.HistogramAlpha = double.Parse(label6.Text);
  1054. this.AppWorkspace.ActiveDocumentWorkspace.HistogramBeta = double.Parse(label5.Text);
  1055. this.AppWorkspace.ActiveDocumentWorkspace.HistogramPercent = (int)numericUpDown1.Value;
  1056. this.AppWorkspace.ActiveDocumentWorkspace.HistogramGamma = double.Parse(numericUpDown2.Value.ToString());
  1057. }
  1058. }
  1059. /// <summary>
  1060. /// 最佳
  1061. /// </summary>
  1062. public void BestButtonMethod()
  1063. {
  1064. OpenCvSharp.Point startIndex = this.getStartIndex(this.AppWorkspace.ActiveDocumentWorkspace.BoxMat/*this.AppWorkspace.ActiveDocumentWorkspace.OldMat*/,
  1065. oldHists, (float)numericUpDown1.Value);
  1066. //计算对比度
  1067. label6.Text = (256.0 / (startIndex.Y - startIndex.X)).ToString("f2");
  1068. trackBar2.Value = Math.Min(trackBar2.Maximum, (int)(double.Parse(label6.Text) * 100));
  1069. //计算亮度
  1070. label5.Text = ((0 - startIndex.X - startIndex.Y) / 510.0).ToString("f2");
  1071. trackBar1.Value = (int)(double.Parse(label5.Text) * 100);
  1072. }
  1073. /// <summary>
  1074. /// 最大最小
  1075. /// </summary>
  1076. public void MaxMinButtonMethod()
  1077. {
  1078. OpenCvSharp.Point startIndex = this.getStartIndex(this.AppWorkspace.ActiveDocumentWorkspace.BoxMat/*this.AppWorkspace.ActiveDocumentWorkspace.OldMat*/,
  1079. oldHists, 0);
  1080. //计算对比度
  1081. label6.Text = (256.0 / (startIndex.Y - startIndex.X)).ToString("f2");
  1082. trackBar2.Value = Math.Min(trackBar2.Maximum, (int)(double.Parse(label6.Text) * 100));
  1083. //计算亮度
  1084. label5.Text = ((0 - startIndex.X - startIndex.Y) / 510.0).ToString("f2");
  1085. trackBar1.Value = (int)(double.Parse(label5.Text) * 100);
  1086. }
  1087. /// <summary>
  1088. /// 原始状态
  1089. /// </summary>
  1090. public void OriginButtonMethod()
  1091. {
  1092. this.trackBar1.Value = -50;
  1093. this.trackBar2.Value = 100;
  1094. this.trackBar3.Value = 100;
  1095. label5.Text = (trackBar1.Value / 100.0).ToString("f2");
  1096. label6.Text = (trackBar2.Value / 100.0).ToString("f2");
  1097. numericUpDown2.Value = decimal.Parse((trackBar3.Value / 100.0).ToString("f2"));
  1098. }
  1099. /// <summary>
  1100. /// 伽马0.45
  1101. /// </summary>
  1102. public void Gamma45ButtonMethod()
  1103. {
  1104. this.trackBar3.Value = 45;
  1105. this.numericUpDown2.Value = decimal.Parse((trackBar3.Value / 100.0).ToString("f2"));
  1106. }
  1107. /// <summary>
  1108. /// 重新处理图片
  1109. /// https://blog.csdn.net/qq_20095389/article/details/83658878
  1110. /// https://blog.csdn.net/lantishua/article/details/46377325
  1111. /// </summary>
  1112. /// <param name="sender"></param>
  1113. /// <param name="e"></param>
  1114. public void EventIncidentBranch(string sender, bool calc = true)
  1115. {
  1116. switch (sender)
  1117. {
  1118. case "trackBar1":
  1119. this.label5.Text = (trackBar1.Value / 100.0).ToString("f2");
  1120. break;
  1121. case "trackBar2":
  1122. this.label6.Text = (trackBar2.Value / 100.0).ToString("f2");
  1123. break;
  1124. case "trackBar3":
  1125. this.numericUpDown2.Value = decimal.Parse((trackBar3.Value / 100.0).ToString("f2"));
  1126. break;
  1127. case "label6":
  1128. if(this.AppWorkspace.ActiveDocumentWorkspace != null)
  1129. this.AppWorkspace.ActiveDocumentWorkspace.HistogramAlpha = double.Parse(label6.Text);
  1130. break;
  1131. case "label5":
  1132. if (this.AppWorkspace.ActiveDocumentWorkspace != null)
  1133. this.AppWorkspace.ActiveDocumentWorkspace.HistogramBeta = double.Parse(label5.Text);
  1134. break;
  1135. case "numericUpDown1":
  1136. if (this.AppWorkspace.ActiveDocumentWorkspace != null)
  1137. this.AppWorkspace.ActiveDocumentWorkspace.HistogramPercent = (int)numericUpDown1.Value;
  1138. break;
  1139. case "numericUpDown2":
  1140. if (this.AppWorkspace.ActiveDocumentWorkspace != null)
  1141. this.AppWorkspace.ActiveDocumentWorkspace.HistogramGamma = double.Parse(numericUpDown2.Value.ToString());
  1142. trackBar3.Value = (int)(numericUpDown2.Value * 100);
  1143. break;
  1144. default:
  1145. this.label5.Text = (trackBar1.Value / 100.0).ToString("f2");
  1146. this.label6.Text = (trackBar2.Value / 100.0).ToString("f2");
  1147. this.numericUpDown2.Value = decimal.Parse((trackBar3.Value / 100.0).ToString("f2"));
  1148. break;
  1149. }
  1150. //重新计算
  1151. if(calc)
  1152. this.scrollMethod();
  1153. //更新直方图
  1154. this.updateHistogramRect(true);
  1155. }
  1156. /// <summary>
  1157. /// 拖动左侧三角形
  1158. /// </summary>
  1159. /// <param name="sender"></param>
  1160. /// <param name="e"></param>
  1161. private void ucTrackBar1_Value1Changed(object sender, EventArgs e)
  1162. {
  1163. this.RemoveAllEvent();
  1164. OpenCvSharp.Point startIndex = new OpenCvSharp.Point(ucTrackBar1.Value1, ucTrackBar1.Value3);
  1165. //计算对比度
  1166. label6.Text = (256.0 / (startIndex.Y - startIndex.X)).ToString("f2");
  1167. trackBar2.Value = Math.Min(trackBar2.Maximum, (int)(double.Parse(label6.Text) * 100));
  1168. //计算亮度
  1169. label5.Text = ((0 - startIndex.X - startIndex.Y) / 510.0).ToString("f2");
  1170. trackBar1.Value = (int)(double.Parse(label5.Text) * 100);
  1171. this.AddAllEvent();
  1172. }
  1173. /// <summary>
  1174. /// 拖动中间三角形
  1175. /// </summary>
  1176. /// <param name="sender"></param>
  1177. /// <param name="e"></param>
  1178. private void ucTrackBar1_Value2Changed(object sender, EventArgs e)
  1179. {
  1180. this.RemoveAllEvent();
  1181. //计算gamma值
  1182. double gamma = 1.0 / Math.Log((ucTrackBar1.Value2 - ucTrackBar1.Value1) / (ucTrackBar1.Value3 - ucTrackBar1.Value1), 0.5);
  1183. gamma = Math.Max(0.01, gamma);
  1184. this.trackBar3.Value = Math.Min(299, (int)(gamma * 100));
  1185. numericUpDown2.Value = decimal.Parse(Math.Min(2.99, gamma).ToString("f2"));
  1186. this.AddAllEvent();
  1187. }
  1188. /// <summary>
  1189. /// 拖动右侧三角形
  1190. /// </summary>
  1191. /// <param name="sender"></param>
  1192. /// <param name="e"></param>
  1193. private void ucTrackBar1_Value3Changed(object sender, EventArgs e)
  1194. {
  1195. this.RemoveAllEvent();
  1196. OpenCvSharp.Point startIndex = new OpenCvSharp.Point(ucTrackBar1.Value1, ucTrackBar1.Value3);
  1197. //计算对比度
  1198. label6.Text = (256.0 / (startIndex.Y - startIndex.X)).ToString("f2");
  1199. trackBar2.Value = Math.Min(trackBar2.Maximum, (int)(double.Parse(label6.Text) * 100));
  1200. //计算亮度
  1201. label5.Text = ((0 - startIndex.X - startIndex.Y) / 510.0).ToString("f2");
  1202. trackBar1.Value = (int)(double.Parse(label5.Text) * 100);
  1203. this.AddAllEvent();
  1204. }
  1205. /// <summary>
  1206. /// 亮度改变
  1207. /// </summary>
  1208. /// <param name="sender"></param>
  1209. /// <param name="e"></param>
  1210. private void trackBar1_Scroll(object sender, EventArgs e)
  1211. {
  1212. this.RemoveAllEvent();
  1213. this.label5.Text = (trackBar1.Value / 100.0).ToString("f2");
  1214. this.AddAllEvent();
  1215. }
  1216. /// <summary>
  1217. /// 对比度改变
  1218. /// </summary>
  1219. /// <param name="sender"></param>
  1220. /// <param name="e"></param>
  1221. private void trackBar2_Scroll(object sender, EventArgs e)
  1222. {
  1223. this.RemoveAllEvent();
  1224. label6.Text = (trackBar2.Value / 100.0).ToString("f2");
  1225. this.AddAllEvent();
  1226. }
  1227. /// <summary>
  1228. /// gamma改变
  1229. /// gamma值小于1时,会拉伸图像中灰度级较低的区域,同时会压缩灰度级较高的部分
  1230. /// gamma值大于1时,会拉伸图像中灰度级较高的区域,同时会压缩灰度级较低的部分
  1231. /// </summary>
  1232. /// <param name="sender"></param>
  1233. /// <param name="e"></param>
  1234. private void trackBar3_Scroll(object sender, EventArgs e)
  1235. {
  1236. this.RemoveAllEvent();
  1237. numericUpDown2.Value = decimal.Parse((trackBar3.Value / 100.0).ToString("f2"));
  1238. this.AddAllEvent();
  1239. }
  1240. }
  1241. }