整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Python Matplotlib直方圖:揭秘?cái)?shù)據(jù)分

          Python Matplotlib直方圖:揭秘?cái)?shù)據(jù)分布可視化的藝術(shù)

          Python數(shù)據(jù)科學(xué)和Web開發(fā)領(lǐng)域,可視化是理解和表達(dá)數(shù)據(jù)的重要手段之一。其中,直方圖作為一種統(tǒng)計(jì)圖形,能夠清晰地展現(xiàn)數(shù)據(jù)分布的特點(diǎn),幫助我們快速識別集中趨勢、分散程度以及其他潛在模式。本文將以Python中最常用的可視化庫Matplotlib為基礎(chǔ),詳細(xì)介紹如何利用其內(nèi)置的hist()函數(shù)繪制高質(zhì)量的直方圖,并結(jié)合實(shí)際Web應(yīng)用展示如何將直方圖嵌入到Web界面中。


          直方圖基礎(chǔ)概念

          直方圖是一種統(tǒng)計(jì)圖形,它將連續(xù)變量的值劃分為一系列區(qū)間(稱為“bins”),并通過柱狀的高度表示落在各個(gè)區(qū)間內(nèi)的數(shù)據(jù)點(diǎn)數(shù)量。這種圖形特別適用于展示數(shù)據(jù)的頻數(shù)分布,即數(shù)據(jù)集中在哪些數(shù)值范圍。

          Matplotlib繪制直方圖

          首先,讓我們通過一個(gè)簡單的例子來看看如何使用Matplotlib繪制直方圖:

          import matplotlib.pyplot as plt
          import numpy as np
          
          # 創(chuàng)建一組模擬數(shù)據(jù)
          data=np.random.normal(size=1000)
          
          # 使用hist()函數(shù)繪制直方圖
          plt.hist(data, bins=30, edgecolor='black')  # 參數(shù)bins決定區(qū)間個(gè)數(shù)
          
          plt.xlabel('Value Range')
          plt.ylabel('Frequency')
          plt.title('Normal Distribution Histogram')
          
          # 顯示圖形
          plt.show()
          

          直方圖參數(shù)詳解

          • bins:指定直方圖的區(qū)間數(shù)量或直接提供區(qū)間邊界列表。
          • density:若設(shè)為True,則會計(jì)算頻率密度而非頻數(shù),使得所有直方圖的總面積為1,便于比較不同數(shù)據(jù)集的分布形態(tài)。
          • range:設(shè)定數(shù)據(jù)值的有效范圍,超出此范圍的數(shù)據(jù)會被忽略。
          • alpha:透明度設(shè)置,可以疊加多個(gè)直方圖以對比不同數(shù)據(jù)集。
          • histtype:可以選擇直方圖類型,如’bar’(默認(rèn))或’stepfilled’等。

          高級直方圖應(yīng)用場景

          1. 多組數(shù)據(jù)對比

          在同一張圖上對比兩組或多組數(shù)據(jù)的分布情況:

          data1=np.random.normal(loc=0, scale=1, size=1000)
          data2=np.random.normal(loc=1, scale=1.5, size=1000)
          
          fig, ax=plt.subplots()
          ax.hist(data1, bins=30, alpha=0.5, label='Data Set 1')
          ax.hist(data2, bins=30, alpha=0.5, label='Data Set 2')
          
          ax.set_xlabel('Value')
          ax.set_ylabel('Density')
          ax.legend()
          
          plt.show()
          

          2. 自定義顏色、樣式及誤差條

          colors=['tab:blue', 'tab:orange']
          edgecolors=['black'] * 2
          weights=[np.ones_like(data1), 0.5 * np.ones_like(data2)]
          
          fig, ax=plt.subplots()
          ax.hist([data1, data2], bins=30, color=colors, edgecolor=edgecolors, weights=weights)
          
          plt.show()
          

          直方圖在Web開發(fā)中的應(yīng)用

          在Web應(yīng)用中,通常需要將直方圖轉(zhuǎn)化為可嵌入網(wǎng)頁的靜態(tài)圖像或交互式圖表。例如,借助Flask框架,我們可以生成直方圖圖片并在HTML頁面中展示:

          from flask import Flask, render_template
          
          app=Flask(__name__)
          
          @app.route('/')
          def histogram_example():
              # 同上創(chuàng)建數(shù)據(jù)并繪制直方圖
              ...
              
              # 保存為圖片
              fig.savefig('histogram.png', dpi=300)
          
              return render_template('index.html', image_url='/static/histogram.png')
          
          if __name__=='__main__':
              app.run(debug=True)
          

          動(dòng)態(tài)直方圖與交互式Web應(yīng)用

          對于更高級的應(yīng)用場景,可以考慮采用Bokeh、Plotly等支持Web交互式的圖表庫,它們可以直接生成可在瀏覽器中動(dòng)態(tài)縮放和平移的直方圖。

          總之,直方圖作為揭示數(shù)據(jù)分布特征的強(qiáng)大工具,在Python Web開發(fā)中扮演了重要角色。通過深入理解和熟練運(yùn)用Matplotlib或其他相關(guān)庫,開發(fā)者可以設(shè)計(jì)出富有洞察力的數(shù)據(jù)可視化界面,提升用戶體驗(yàn)和決策效率。

          話不多說直接上代碼

          模板

          源數(shù)據(jù)格式,小編用得是動(dòng)態(tài)數(shù)據(jù)就不給大家展示了就放個(gè)格式給大家看看吧

          data=[

          {

          letter: "白皮雞蛋",

          child: {

          category: "0",

          value: "459.00"

          }

          },

          {

          letter: "紅皮雞蛋",

          child: {

          category: "0",

          value: "389.00"

          }

          },....]

          接下來是重點(diǎn)啊代碼有點(diǎn)多(前方高能)

          d3在vue中安裝也很簡單 直接 npm install d3

          import * as d3 from "d3";

          我是封裝在chart函數(shù)中的(兩個(gè)參數(shù)分別是源數(shù)據(jù)和圖像掛載dom在vue中直接用this.$refs.cil其他地方的用法和JQ類似)

          function chart(data, myEle) {

          {

          var margin={

          top: 20,

          right: 50,

          bottom: 50,

          left: 90

          };

          var svgWidth=window.screen.width -margin.right -margin.left; // 檢測屏幕

          var svgHeight=500;

          //創(chuàng)建各個(gè)面的顏色數(shù)組

          var mainColorList=[

          "#f6e242",

          "#ebec5b",

          "#d2ef5f",

          "#b1d894",

          "#97d5ad",

          "#82d1c0",

          "#70cfd2",

          "#63c8ce",

          "#50bab8",

          "#38a99d"

          ];

          var topColorList=[

          "#e9d748",

          "#d1d252",

          "#c0d75f",

          "#a2d37d",

          "#83d09e",

          "#68ccb6",

          "#5bc8cb",

          "#59c0c6",

          "#3aadab",

          "#2da094"

          ];

          var rightColorList=[

          "#dfce51",

          "#d9db59",

          "#b9d54a",

          "#9ece7c",

          "#8ac69f",

          "#70c3b1",

          "#65c5c8",

          "#57bac0",

          "#42aba9",

          "#2c9b8f"

          ];

          // console.log(this.$refs.cil)

          var svg=d3

          .select(myEle)

          .append("svg")

          .attr("width", svgWidth)

          .attr("height", svgHeight)

          .attr("id", "svg-column");

          // 創(chuàng)建X軸序數(shù)比例尺

          function addXAxis() {

          var transform=d3.geoTransform({

          point: function (x, y) {

          this.stream.point(x, y);

          }

          }); //定義幾何路徑

          var path=d3.geoPath().projection(transform);

          var xLinearScale=d3

          .scaleBand()

          .domain(

          data.map(function (d) {

          return d.letter;

          })

          )

          .range([0, svgWidth - margin.right - margin.left], 0.1);

          var xAxis=d3.axisBottom(xLinearScale).ticks(data.length); //繪制X軸

          var xAxisG=svg

          .append("g")

          .call(xAxis)

          .attr(

          "transform",

          "translate(" + margin.left + "," + (svgHeight - margin.bottom) +")"

          ); //刪除原X軸

          xAxisG.select("path").remove();

          xAxisG.selectAll("line").remove(); //繪制新的立體X軸

          xAxisG

          .append("path")

          .datum({

          type: "Polygon",

          coordinates: [

          [

          [20, 0],

          [0, 15],

          [svgWidth - margin.right - margin.left, 15],

          [svgWidth + 20 - margin.right - margin.left, 0],

          [20, 0]

          ]

          ]

          })

          .attr("d", path)

          .attr("fill", "rgb(187,187,187)");

          xAxisG

          .selectAll("text")

          .attr("fill", "#646464")

          .attr("class", 'rotate_txt')

          .attr("transform-origin", "50% top 0")

          .attr("transform", "translate(0,20)");

          dataProcessing(xLinearScale); //核心算法

          }

          var yLinearScale;

          //創(chuàng)建y軸的比例尺渲染y軸

          function addYScale() {

          yLinearScale=d3

          .scaleLinear()

          .domain([

          0,

          d3.max(data, function (d, i) {

          return d.child.value * 1;

          }) * 1.2

          ])

          .range([svgHeight - margin.top - margin.bottom, 0]);

          //定義Y軸比例尺以及刻度

          var yAxis=d3.axisLeft(yLinearScale).ticks(6);

          //繪制Y軸

          var yAxisG=svg

          .append("g")

          .call(yAxis)

          .attr(

          "transform",

          "translate(" + (margin.left + 10) + "," + margin.top + ")"

          );

          yAxisG

          .selectAll("text")

          .attr("font-size", "18px")

          .attr("fill", "#636363");

          //刪除原Y軸路徑和tick

          yAxisG.select("path").remove();

          yAxisG.selectAll("line").remove();

          }

          //核心算法思路是

          function dataProcessing(xLinearScale) {

          var angle=Math.PI / 2.3;

          for (var i=0; i < data.length; i++) {

          var d=data[i];

          var depth=10;

          d.ow=xLinearScale.bandwidth() * 0.7;

          d.ox=xLinearScale(d.letter);

          d.oh=1;

          d.p1={

          x: Math.cos(angle) * d.ow,

          y: -Math.sin(angle) - depth

          };

          d.p2={

          x: d.p1.x + d.ow,

          y: d.p1.y

          };

          d.p3={

          x: d.p2.x,

          y: d.p2.y + d.oh

          };

          }

          }

          //tip的創(chuàng)建方法

          var tipTimerConfig={

          longer: 0,

          target: null,

          exist: false,

          winEvent: window.event,

          boxHeight: 398,

          boxWidth: 376,

          maxWidth: 376,

          maxHeight: 398,

          tooltip: null,

          showTime: 3500,

          hoverTime: 300,

          displayText: "",

          show: function (val, e) {

          "use strict";

          var me=this;

          if (e !=null) {

          me.winEvent=e;

          }

          me.displayText=val;

          me.calculateBoxAndShow();

          me.createTimer();

          },

          calculateBoxAndShow: function () {

          "use strict";

          var me=this;

          var _x=0;

          var _y=0;

          var _w=document.documentElement.scrollWidth;

          var _h=document.documentElement.scrollHeight;

          var wScrollX=window.scrollX || document.body.scrollLeft;

          var wScrollY=window.scrollY || document.body.scrollTop;

          var xMouse=me.winEvent.x + wScrollX;

          if (_w - xMouse < me.boxWidth) {

          _x=xMouse - me.boxWidth - 10;

          } else {

          _x=xMouse;

          }

          var _yMouse=me.winEvent.y + wScrollY;

          if (_h - _yMouse < me.boxHeight + 18) {

          _y=_yMouse - me.boxHeight - 25;

          } else {

          _y=_yMouse + 18;

          }

          me.addTooltip(_x, _y);

          },

          addTooltip: function (page_x, page_y) {

          "use strict";

          var me=this;

          me.tooltip=document.createElement("div");

          me.tooltip.style.left=page_x + "px";

          me.tooltip.style.top=page_y + "px";

          me.tooltip.style.position="absolute";

          me.tooltip.style.width=me.boxWidth + "px";

          me.tooltip.style.height=me.boxHeight + "px";

          me.tooltip.className="three-tooltip";

          var divInnerHeader=me.createInner();

          divInnerHeader.innerHTML=me.displayText;

          me.tooltip.appendChild(divInnerHeader);

          document.body.appendChild(me.tooltip);

          },

          createInner: function () {

          "use strict";

          var me=this;

          var divInnerHeader=document.createElement("div");

          divInnerHeader.style.width=me.boxWidth + "px";

          divInnerHeader.style.height=me.boxHeight + "px";

          return divInnerHeader;

          },

          ClearDiv: function () {

          "use strict";

          var delDiv=document.body.getElementsByClassName("three-tooltip");

          for (var i=delDiv.length - 1; i >=0; i--) {

          document.body.removeChild(delDiv[i]);

          }

          },

          createTimer: function (delTarget) {

          "use strict";

          var me=this;

          var delTip=me.tooltip;

          var delTarget=tipTimerConfig.target;

          var removeTimer=window.setTimeout(function () {

          try {

          if (delTip !=null) {

          document.body.removeChild(delTip);

          if (tipTimerConfig.target==delTarget) {

          me.exist=false;

          }

          }

          clearTimeout(removeTimer);

          } catch (e) {

          clearTimeout(removeTimer);

          }

          }, me.showTime);

          },

          hoverTimerFn: function (showTip, showTarget) {

          "use strict";

          var me=this;

          var showTarget=tipTimerConfig.target;

          var hoverTimer=window.setInterval(function () {

          try {

          if (tipTimerConfig.target !=showTarget) {

          clearInterval(hoverTimer);

          } else if (

          !tipTimerConfig.exist &&

          new Date().getTime() - me.longer > me.hoverTime

          ) {

          //show

          tipTimerConfig.show(showTip);

          tipTimerConfig.exist=true;

          clearInterval(hoverTimer);

          }

          } catch (e) {

          clearInterval(hoverTimer);

          }

          }, tipTimerConfig.hoverTime);

          }

          };

          var createTooltipTableData=function (info) {

          var ary=[];

          ary.push("<div class='tip-hill-div'>");

          ary.push("<p>" + info.letter +' '+ info.child.value + "</p>");

          ary.push("</div>");

          return ary.join("");

          };

          // 核心算法寫完,就到了最終的渲染了

          function addColumn() {

          function clumnMouseover(d) {

          d3.select(this)

          .selectAll(".transparentPath")

          .attr("opacity", 0.8);

          // 添加 div

          tipTimerConfig.target=this;

          tipTimerConfig.longer=new Date().getTime();

          tipTimerConfig.exist=false;

          //獲取坐標(biāo)

          tipTimerConfig.winEvent={

          x: event.clientX - 100,

          y: event.clientY

          };

          tipTimerConfig.boxHeight=50;

          tipTimerConfig.boxWidth=140;

          //hide

          tipTimerConfig.ClearDiv();

          //show

          tipTimerConfig.hoverTimerFn(createTooltipTableData(d));

          }

          function clumnMouseout(d) {

          d3.select(this)

          .selectAll(".transparentPath")

          .attr("opacity", 1);

          tipTimerConfig.target=null;

          tipTimerConfig.ClearDiv();

          }

          var g=svg

          .selectAll(".g")

          .data(data)

          .enter()

          .append("g")

          .on("mouseover", clumnMouseover)

          .on("mouseout", clumnMouseout)

          .attr("transform", function (d) {

          return (

          "translate(" +

          (d.ox + margin.left + 20) +

          "," +

          (svgHeight - margin.bottom + 15) +

          ")"

          );

          });

          g.transition()

          .duration(2500)

          .attr("transform", function (d) {

          return (

          "translate(" +

          (d.ox + margin.left + 20) +

          ", " +

          (yLinearScale(d.child.value) + margin.bottom - 15) +

          ")"

          );

          });

          g.append("rect")

          .attr("x", 0)

          .attr("y", 0)

          .attr("class", "transparentPath")

          .attr("width", function (d, i) {

          return d.ow;

          })

          .attr("height", function (d) {

          return d.oh;

          })

          .style("fill", function (d, i) {

          if (!mainColorList[i]) {

          return "#38a99d"

          }

          return mainColorList[i];

          })

          .transition()

          .duration(2500)

          .attr("height", function (d, i) {

          return (

          svgHeight -

          margin.bottom -

          margin.top -

          yLinearScale(d.child.value)

          );

          });

          g.append("path")

          .attr("class", "transparentPath")

          .attr("d", function (d) {

          return (

          "M0,0 L" +

          d.p1.x +

          "," +

          d.p1.y +

          " L" +

          d.p2.x +

          "," +

          d.p2.y +

          " L" +

          d.ow +

          ",0 L0,0"

          );

          })

          .style("fill", function (d, i) {

          if (!topColorList[i]) {

          return "#2da094"

          }

          return topColorList[i];

          });

          g.append("path")

          .attr("class", "transparentPath")

          .attr("d", function (d) {

          return (

          "M" +

          d.ow +

          ",0 L" +

          d.p2.x +

          "," +

          d.p2.y +

          " L" +

          d.p3.x +

          "," +

          d.p3.y +

          " L" +

          d.ow +

          "," +

          d.oh +

          " L" +

          d.ow +

          ",0"

          );

          })

          .style("fill", function (d, i) {

          if (!rightColorList[i]) {

          return "#2c9b8f"

          }

          return rightColorList[i];

          })

          .transition()

          .duration(2500)

          .attr("d", function (d, i) {

          return (

          "M" +

          d.ow +

          ",0 L" +

          d.p2.x +

          "," +

          d.p2.y +

          " L" +

          d.p3.x +

          "," +

          (d.p3.y +

          svgHeight -

          margin.top -

          margin.bottom -

          yLinearScale(d.child.value)) +

          " L" +

          d.ow +

          "," +

          (svgHeight -

          margin.top -

          margin.bottom -

          yLinearScale(d.child.value)) +

          " L" +

          d.ow +

          ",0"

          );

          });

          }

          // 函數(shù)調(diào)用

          addXAxis();

          addYScale();

          addColumn();

          }

          }

          這里提供暴露接口讓組件調(diào)用

          export function showCahrt(data, myEle) {

          return chart(data, myEle)

          }

          這里有個(gè)bug我一直沒有找到很好的解決辦法就是在繪制x軸時(shí)文字的樣式調(diào)整

          就是這里使用.attr("transform", "translate(0,20) rotate(-30deg)")也就是旋轉(zhuǎn)加下移組合是根本不生效只能寫其中的一個(gè)。不知道小伙伴們有沒有什么高見很是期待!

          整篇的代碼有點(diǎn)長其實(shí)整體還是很清晰的 。在最后面

          有收獲的小朋友記得點(diǎn)贊哦

          一)測光

          測光分入射測光和反射測光。顧名思義,入射測光是測量直接照射到被攝體上的光線強(qiáng)度,而反射測光是測量從被攝體反射回來(進(jìn)入相機(jī)鏡頭)的光線強(qiáng)度。相機(jī)的內(nèi)置測光表都是反射測光表。

          反射測光表的工作原理是根據(jù)對被攝體反射的光的測量來估計(jì)入射到被攝體上的光強(qiáng)度。很明顯,估算的結(jié)果依賴于被攝體對光的反射率。因?yàn)楝F(xiàn)實(shí)中場景和被攝體的反射率變化很大,這導(dǎo)致反射測光表可能給出錯(cuò)誤的結(jié)果。

          反射測光表一般采用中度灰來校準(zhǔn)。也就是說,它總是假設(shè)被攝體的黑白顏色是中度灰的,以中度灰的反射率來估算入射光的強(qiáng)度,再?zèng)Q定在給定的光強(qiáng)照度和膠片或影像傳感器的ISO值下的光圈和快門的組合。中度灰是介于純白和純黑之間的灰色,對應(yīng)的反射率是18%,所以又叫做18%灰。

          幾種顏色的18%反射光強(qiáng)

          現(xiàn)在的測光技術(shù)都很發(fā)達(dá),在大多數(shù)場合相機(jī)的內(nèi)置測光表都能給出比較準(zhǔn)確的測光。但在特殊或者極端的條件下,自動(dòng)測光的結(jié)果會和真實(shí)結(jié)果差別較大,必須通過曝光補(bǔ)償來修正。最好在拍攝的時(shí)候就做曝光補(bǔ)償,不要留到后期,因?yàn)殄e(cuò)誤的曝光會讓照片丟失細(xì)節(jié)。(如果想得到比較準(zhǔn)確的反射測光可以使用灰卡,這里不作介紹。)

          因?yàn)榉瓷錅y光表總是假設(shè)被攝體是中度灰的,如果使用有內(nèi)置測光表的相機(jī)拍攝充滿畫面的一張白紙,出來的相片是一張灰顏色的紙;如果使用有內(nèi)置測光表的相機(jī)拍攝充滿畫面的一張黑紙,出來的相片也是一張灰顏色的紙。如果想要白紙出來的相片也是白紙,就要增加一定量的曝光;如果想要黑紙出來的相片也是黑紙,就要減少一定量的曝光。

          要養(yǎng)成這樣的習(xí)慣:每次拍照之前,都要問一下“這個(gè)場景是否是平均的?是否需要曝光補(bǔ)償?”數(shù)碼相機(jī)讓測光變得簡單:可以先用自動(dòng)測光的設(shè)置拍攝一張,查看結(jié)果再?zèng)Q定是否需要曝光補(bǔ)償。

          一些有用的規(guī)律:

          1. 對于測光和逆光的場景、沙灘或者雪景、日落或者具有明亮光源的場景、自然刻畫白色或者非常明亮的被攝體,增加一檔曝光。
          2. 如果光線的反差非常強(qiáng)烈,并且擁有重要細(xì)節(jié)的陰影部位比明亮的部分要暗很多,增加兩檔曝光。
          3. 對于背景比前景暗許多并大許多(例如站在站在暗色墻壁前的膚色明亮的人),降低一檔曝光。
          4. 當(dāng)非常暗的背景占據(jù)畫面的大部分時(shí),降低兩檔曝光。

          (二)直方圖

          相機(jī)的直方圖是個(gè)非常有用的工具,可以幫助拍攝者獲得正確的曝光。所以,學(xué)會讀懂直方圖對提高攝影技術(shù)至關(guān)重要。

          直方圖能直觀地顯示影像的明暗色調(diào)分布,對比度,和曝光。直方圖的定義是:橫軸代表黑白亮度等級(從左到右代表由暗到明的變化),縱軸代表每個(gè)亮度等級下的圖像像素個(gè)數(shù)。亮度由左到右分成256個(gè)等級,從0到255,0代表純黑,255代表純白,128是中度灰。一個(gè)典型的直方圖如下圖所示。(高級相機(jī)可以顯示紅、綠、藍(lán)每個(gè)通道的直方圖。)

          直方圖整體的絕對高度并不重要,因?yàn)橄鄼C(jī)對直方圖做了一定程度的歸一化以保證中間最大的像素值能表示在圖上。有意義的是每個(gè)亮度等級里邊像素?cái)?shù)目的相對分布,即直方圖的形狀。

          拍攝的影像的直方圖取決于以下幾個(gè)因素:(1)拍攝場景的動(dòng)態(tài)范圍;(2)相機(jī)影像傳感器能撲捉到的動(dòng)態(tài)范圍;(3)曝光的選擇。動(dòng)態(tài)范圍由光強(qiáng)分布的最大值和最小值之比(即對比度)來決定,在攝影中由2的冪律指數(shù)即曝光檔數(shù)(或光圈檔數(shù))表示(參見http://blog.sina.com.cn/s/blog_713dd87d0100nt1j.html)。如果真實(shí)場景的動(dòng)態(tài)范圍(即對比度)小于相機(jī)的動(dòng)態(tài)范圍(即相機(jī)能拍下的對比度),那么只要曝光正確,相機(jī)就能拍下場景的整個(gè)動(dòng)態(tài)范圍,得到的直方圖是這樣的:


          顯然這個(gè)直方圖的位置還有調(diào)整的余地:可以整體向左移動(dòng),也可以整體向右移動(dòng),只要不貼到左右兩側(cè)邊緣,都不會導(dǎo)致細(xì)節(jié)丟失。向左移動(dòng)圖像整體變暗(欠曝),噪點(diǎn)會增加。向右移動(dòng)圖像整體變亮,噪點(diǎn)減少。所謂“向右曝光”,說的是讓直方圖盡量靠右,但不要貼到右端,這樣的圖像可以擁有最多的細(xì)節(jié),最少的噪點(diǎn),利于后期處理。

          相反,如果真實(shí)場景的動(dòng)態(tài)范圍大于相機(jī)的動(dòng)態(tài)范圍,那么無論曝光怎樣設(shè)置,都無法一次撲捉到場景的全部動(dòng)態(tài)范圍,只能撲捉到真是動(dòng)態(tài)范圍的一部分,如圖:

          在給定的曝光設(shè)置下,相機(jī)的傳感器能撲捉到光強(qiáng)有個(gè)上限和下限。真實(shí)場景中亮度超過這個(gè)上限的部分,對應(yīng)的傳感器像素白色已經(jīng)達(dá)到極限(不能更白了),全部記錄為“最白”;真實(shí)場景中亮度低于這個(gè)下限的部分,對應(yīng)的傳感器像素黑色達(dá)到極限(不能更黑了),全部記錄為“最黑”。也就是說,比影像傳感器的“最白”更白的部分全部記錄為“最白”,比影像傳感器的“最黑”更黑的部分全部記錄為“最黑”。體現(xiàn)到直方圖上,就是在直方圖的右邊(最白)和左邊(最黑)像素的數(shù)目堆積,形成僅靠兩邊的峰值(如上圖)。這種現(xiàn)象叫做“溢出”,會導(dǎo)致圖像亮部和暗部的細(xì)節(jié)丟失,一般應(yīng)該避免。當(dāng)然,也可以設(shè)置曝光使得亮端的動(dòng)態(tài)全部被拍下,這樣暗端必然溢出;或者使得暗端全部拍下,這樣亮端必然溢出。只要是真實(shí)場景動(dòng)態(tài)范圍超過了相機(jī)的動(dòng)態(tài)范圍,溢出就不可避免。溢出直接導(dǎo)致亮部或暗部的細(xì)節(jié)丟失。

          如果直方圖的左邊溢出,那么圖像圖像暗部信息丟失。如果右邊溢出,那么圖像亮部信息丟失。左右兩邊都溢出,那么圖像亮部和暗部都有信息丟失。拍攝的時(shí)候兩個(gè)方向的溢出都應(yīng)該避免,以保持圖像擁有最多的細(xì)節(jié)。如果無法避免,就要看暗部細(xì)節(jié)更重要一些還是亮部細(xì)節(jié)更重要一些,選擇保留重要的細(xì)節(jié)。數(shù)碼相機(jī)最怕過曝,過曝了細(xì)節(jié)無法在后期恢復(fù);一定程度的欠曝可以在后期恢復(fù),代價(jià)是噪點(diǎn)的增加。這點(diǎn)跟膠片正相反。所以,使用數(shù)碼相機(jī)一定要盡可能避免右方溢出。

          左圖:暗端溢出;右圖:亮端溢出

          完美的標(biāo)準(zhǔn)直方圖是不存在的,因?yàn)橹狈綀D的形狀取決于相機(jī)鏡頭前方的具體景象。好的直方圖是有的。好的直方圖應(yīng)該是左右兩端都沒有溢出,整個(gè)直方圖完整地分布在亮度0到255之間(實(shí)際拍攝中有時(shí)無法做到,總會在一端有溢出,如上所述)。到底是偏左一點(diǎn)好還是偏右一點(diǎn)好,完全取決于拍攝者的意圖。比如要拍攝一幅主要由暗部構(gòu)成的低調(diào)照片,直方圖就要偏左。要拍攝一幅主要由亮部構(gòu)成的高調(diào)照片,直方圖就要偏右。

          相機(jī)的自動(dòng)測光總是努力把直方圖的像素分布平均值位置放在中間(中度灰位置)。如果這不是你要的結(jié)果,你就要通過曝光補(bǔ)償重新拍照來把直方圖往左或者往右來移動(dòng)。直方圖峰值代表了圖像占主導(dǎo)的亮度等級的分布。如果直方圖整體較窄,它表示量度分布在一個(gè)狹窄的區(qū)域,圖像的對比度較低。如果整體分布較寬,代表亮度分布在一個(gè)寬泛的區(qū)域,圖像的對比度較高。如果直方圖出現(xiàn)了相距較遠(yuǎn)的兩個(gè)峰值,那么這個(gè)圖象的對比度非常高。

          左圖:對比度低,色調(diào)單一;右圖:對比度較高,色調(diào)飽滿

          如果想在圖像中保留盡可能多的細(xì)節(jié)以便后期處理,可以選擇盡量向右曝光,即讓直方圖的最右邊貼在直方圖的右端但不要溢出。向右曝光還可以盡可能地減少噪點(diǎn)(提高整體信噪比)。這樣的照片看上去幾乎總是白亮亮的,需要后期處理得到想要的結(jié)果。

          下面是一些具體直方圖例子:

          光線色調(diào)非常復(fù)雜,左右溢出同時(shí)存在,缺少中色調(diào)



          低調(diào)場景,直方圖偏左



          高調(diào)場景,直方圖偏右



          其它幾個(gè)例子

          場景具有幾近完美的亮度分布


          低調(diào)照片,完美地?fù)渥降桨挡浚ū尘埃┖土敛浚ㄔ铝粒?/p>


          雖然直方圖整體偏右(過曝),但前當(dāng)?shù)胤磻?yīng)了眼睛看到的景象


          主站蜘蛛池模板: 一区二区三区视频| 99精品国产一区二区三区2021 | 合区精品久久久中文字幕一区| 国产精品一区二区久久精品| 中文字幕在线一区二区在线| 亚洲综合色一区二区三区小说| 少妇人妻精品一区二区三区| 国产成人精品久久一区二区三区av| 国产激情精品一区二区三区| 一区二区三区四区精品| 国产精品 一区 在线| 国产福利电影一区二区三区,亚洲国模精品一区 | 久久久久人妻一区精品| 无码人妻一区二区三区精品视频| 日韩一区二区精品观看| 久久99国产一区二区三区| 日韩制服国产精品一区| 午夜AV内射一区二区三区红桃视| 久久精品午夜一区二区福利| 中文字幕一区二区三区人妻少妇| 国产精品高清视亚洲一区二区 | 国产丝袜视频一区二区三区| 国产精品日本一区二区在线播放 | 乱色精品无码一区二区国产盗| 2020天堂中文字幕一区在线观 | 午夜视频一区二区| 中文字幕人妻第一区| 国产成人一区二区三区精品久久| 国产福利电影一区二区三区久久久久成人精品综合 | 色久综合网精品一区二区| 日韩精品一区二区三区中文精品| 呦系列视频一区二区三区| 国产精品福利一区| 国产AV国片精品一区二区| 国产亚洲一区二区三区在线观看 | 亚洲中文字幕一区精品自拍| 在线观看精品视频一区二区三区| 亚洲福利视频一区二区| 91福利视频一区| 国产亚洲综合一区二区三区| 国内精品无码一区二区三区|