说真话不该被屏蔽 發表於 2019-6-11 22:09:00

(一)OpenCV-Python学习—基础知识

<p style="text-align: left">  opencv是一个强大的图像处理和计算机视觉库,实现了很多实用算法,值得学习和深究下。方便大家阅读,整理了下文章链接合集:</p>
<p style="text-align: left">(一)OpenCV-Python学习—基础知识</p>
<p style="text-align: left">(二)OpenCV-Python学习—对比度增强</p>
<p style="text-align: left">(三)OpenCV-Python学习—图像平滑</p>
<p style="text-align: left">(四)OpenCV-Python学习—形态学处理</p>
<p style="text-align: left">(五)OpenCV-Python学习—边缘检测1</p>
<p style="text-align: left">(六)OpenCV-Python学习—边缘检测2</p>
<p style="text-align: left">(七)OpenCV-Python学习—几何形状拟合</p>
<p style="text-align: left">(八)OpenCV-Python学习—轮廓查找,绘制和拟合</p>
<p style="text-align: left">(九)OpenCV-Python学习—图像傅里叶变换</p>
<p style="text-align: left">(十)OpenCV-Python学习—频率域滤波</p>
<p><span style="font-size: 18px"><strong>1.opencv包安装</strong></span></p>
<p>·  这里直接安装opencv-python包(非官方): pip install opencv-python</p>
<p>   官方文档:https://opencv-python-tutroals.readthedocs.io/en/latest/</p>
<p><span style="font-size: 18px"><strong>2. opencv简单图像处理</strong></span></p>
<p>  <span style="font-size: 15px"><strong>2.1 图像像素存储形式</strong></span></p>
<p>    首先得了解下图像在计算机中存储形式:(为了方便画图,每列像素值都写一样了)</p>
<p>    对于只有黑白颜色的灰度图,为单通道,一个像素块对应矩阵中一个数字,数值为0到255, 其中0表示最暗(黑色) ,255表示最亮(白色)</p>
<p>    <img src="https://img2018.cnblogs.com/blog/1483773/201905/1483773-20190526153832514-1217750130.png"></p>
<p>&nbsp;</p>
<p>    对于采用RGB模式的彩色图片,为三通道图,Red、Green、Blue三原色,按不同比例相加,一个像素块对应矩阵中的一个向量, 如,分别表示三种颜色的比列, 即对应深度上的数字,如下图所示:</p>
<p>    <img src="https://img2018.cnblogs.com/blog/1483773/201905/1483773-20190526153914949-1975709262.png"></p>
<p>    需要注意的是,由于历史遗留问题,opencv采用BGR模式,而不是RGB</p>
<p> <span style="font-size: 15px"><strong> 2.2 图像读取和写入</strong></span></p>
<p>    cv2.imread()</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">imread(img_path,flag) 读取图片,返回图片对象
    img_path: 图片的路径,即使路径错误也不会报错,但打印返回的图片对象为None
    flag:cv2.IMREAD_COLOR,读取彩色图片,图片透明性会被忽略,为默认参数,也可以传入1
          cv2.IMREAD_GRAYSCALE,按灰度模式读取图像,也可以传入0
          cv2.IMREAD_UNCHANGED,读取图像,包括其alpha通道,也可以传入</span>-<span style="color: rgba(128, 0, 128, 1)">1</span></pre>
</div>
<p>    cv2.imshow()</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">imshow(window_name,img):显示图片,窗口自适应图片大小
    window_name: 指定窗口的名字
    img:显示的图片对象
    可以指定多个窗口名称,显示多个图片
   
waitKey(millseconds)键盘绑定事件,阻塞监听键盘按键,返回一个数字(不同按键对应的数字不同)
    millseconds: 传入时间毫秒数,在该时间内等待键盘事件;传入0时,会一直等待键盘事件
   
destroyAllWindows(window_name)
    window_name: 需要关闭的窗口名字,不传入时关闭所有窗口</span></pre>
</div>
<p>    cv2.imwrite()</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">imwrite(img_path_name,img)
    img_path_name:保存的文件名
    img:文件对象</span></pre>
</div>
<p>  使用示例:</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_8dad4e6b-ea42-457f-9aca-c9ec245a7362" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_8dad4e6b-ea42-457f-9aca-c9ec245a7362" class="cnblogs_code_hide">
<pre>#coding:utf-<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">

import cv2
img </span>= cv2.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\roi.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
# print(img.shape)
img_gray </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,img_threshold </span>= cv2.threshold(img_gray,<span style="color: rgba(128, 0, 128, 1)">127</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,cv2.THRESH_BINARY)
cv2.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img)
cv2.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">thre</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img_threshold)

key </span>= cv2.waitKey(<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> key==<span style="color: rgba(128, 0, 128, 1)">27</span><span style="color: rgba(0, 0, 0, 1)">: #按esc键时,关闭所有窗口
    print(key)
    cv2.destroyAllWindows()
cv2.imwrite(r</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\thre.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span>,img_threshold)</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> <strong><span style="font-size: 15px"> 2.3 图像像素获取和编辑</span></strong></p>
<p>    像素值获取:</p>
<div class="cnblogs_code">
<pre>img = cv2.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\roi.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

#获取和设置
pixel </span>= img[<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>]#[<span style="color: rgba(128, 0, 128, 1)">57</span> <span style="color: rgba(128, 0, 128, 1)">63</span> <span style="color: rgba(128, 0, 128, 1)">68</span>],获取(<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">)处的像素值
img[</span><span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>]=[<span style="color: rgba(128, 0, 128, 1)">57</span>,<span style="color: rgba(128, 0, 128, 1)">63</span>,<span style="color: rgba(128, 0, 128, 1)">99</span><span style="color: rgba(0, 0, 0, 1)">] #设置像素值
b </span>= img[<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>]    #<span style="color: rgba(128, 0, 128, 1)">57</span>, 获取(<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">)处,blue通道像素值
g </span>= img[<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">1</span>]    #<span style="color: rgba(128, 0, 128, 1)">63</span><span style="color: rgba(0, 0, 0, 1)">
r </span>= img[<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">2</span>]      #<span style="color: rgba(128, 0, 128, 1)">68</span><span style="color: rgba(0, 0, 0, 1)">
r </span>= img[<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">2</span>]=<span style="color: rgba(128, 0, 128, 1)">99</span><span style="color: rgba(0, 0, 0, 1)">    #设置red通道值

#获取和设置
piexl </span>= img.item(<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">)
img.itemset((</span><span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">2</span>),<span style="color: rgba(128, 0, 128, 1)">99</span>)</pre>
</div>
<p>    图片性质</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">import cv2
img </span>= cv2.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\roi.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

#rows,cols,channels
img.shape   #返回(</span><span style="color: rgba(128, 0, 128, 1)">280</span>, <span style="color: rgba(128, 0, 128, 1)">450</span>, <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">), 宽280(rows),长450(cols),3通道(channels)
#size
img.size    #返回378000,所有像素数量,</span>=<span style="color: rgba(128, 0, 128, 1)">280</span>*<span style="color: rgba(128, 0, 128, 1)">450</span>*<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">
#type
img.dtype   #dtype(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">uint8</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>   ROI截取(Range of Interest)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">#ROI,Range of instrest
roi </span>= img[<span style="color: rgba(128, 0, 128, 1)">100</span>:<span style="color: rgba(128, 0, 128, 1)">200</span>,<span style="color: rgba(128, 0, 128, 1)">300</span>:<span style="color: rgba(128, 0, 128, 1)">400</span><span style="color: rgba(0, 0, 0, 1)">]#截取100行到200行,列为300到400列的整块区域
img[</span><span style="color: rgba(128, 0, 128, 1)">50</span>:<span style="color: rgba(128, 0, 128, 1)">150</span>,<span style="color: rgba(128, 0, 128, 1)">200</span>:<span style="color: rgba(128, 0, 128, 1)">300</span>] =<span style="color: rgba(0, 0, 0, 1)"> roi   #将截取的roi移动到该区域 (50到100行,200到300列)
b </span>= img[:,:,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">]#截取整个蓝色通道

b,g,r </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.split(img) #截取三个通道,比较耗时
img </span>= cv2.merge((b,g,r))</pre>
</div>
<p><span style="font-size: 16px"><strong>  2.4 添加边界(padding)  </strong></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.copyMakeBorder()
    参数:
      img:图像对象
      top,bottom,left,right: 上下左右边界宽度,单位为像素值
      borderType:
            cv2.BORDER_CONSTANT, 带颜色的边界,需要传入另外一个颜色值
            cv2.BORDER_REFLECT, 边缘元素的镜像反射做为边界
            cv2.BORDER_REFLECT_101</span>/<span style="color: rgba(0, 0, 0, 1)">cv2.BORDER_DEFAULT
            cv2.BORDER_REPLICATE, 边缘元素的复制做为边界
            CV2.BORDER_WRAP
      value: borderType为cv2.BORDER_CONSTANT时,传入的边界颜色值,如[</span><span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>]</pre>
</div>
<p>    使用示例:</p>
<div class="cnblogs_code"><img alt="" id="code_img_closed_1817ce0c-8f6c-4789-9011-7104982efcbd" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_1817ce0c-8f6c-4789-9011-7104982efcbd" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_1817ce0c-8f6c-4789-9011-7104982efcbd" class="cnblogs_code_hide">
<pre>#coding:utf-<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">


import cv2 </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> cv
import matplotlib.pyplot </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> plt

img2 </span>= cv.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\dog.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
img </span>=<span style="color: rgba(0, 0, 0, 1)"> cv.cvtColor(img2,cv.COLOR_BGR2RGB)#matplotlib的图像为RGB格式
constant </span>= cv.copyMakeBorder(img,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,cv.BORDER_CONSTANT,value=[<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">]) #绿色
reflect </span>= cv.copyMakeBorder(img,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)">,cv.BORDER_REFLECT)
reflect01 </span>= cv.copyMakeBorder(img,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)">,cv.BORDER_REFLECT_101)
replicate </span>= cv.copyMakeBorder(img,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)">,cv.BORDER_REPLICATE)
wrap </span>= cv.copyMakeBorder(img,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span>,<span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)">,cv.BORDER_WRAP)
titles </span>= [<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">constant</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">reflect</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">reflect01</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">replicate</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">wrap</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]
images </span>=<span style="color: rgba(0, 0, 0, 1)">

</span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> range(<span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">):
    plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">2</span>,<span style="color: rgba(128, 0, 128, 1)">3</span>,i+<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">),plt.imshow(images),plt.title(titles)
    plt.xticks([]),plt.yticks([])
plt.show()





</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>    <img alt="" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601115405976-1234855474.png"></p>
<p> <span style="font-size: 15px"><strong> 2.5 像素算术运算</strong></span></p>
<p>      cv2.add()&nbsp; 相加的两个图片,应该有相同的大小和通道</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.add()
    参数:
      img1:图片对象1
      img2:图片对象2
      mask:None (掩膜,一般用灰度图做掩膜,img1和img2相加后,和掩膜与运算,从而达到掩盖部分区域的目的)
      dtype:</span>-<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">

注意:图像相加时应该用cv2.add(img1,img2)代替img1</span>+<span style="color: rgba(0, 0, 0, 1)">img2   
      </span>&gt;&gt;&gt; x = np.uint8([<span style="color: rgba(128, 0, 128, 1)">250</span><span style="color: rgba(0, 0, 0, 1)">])
      </span>&gt;&gt;&gt; y = np.uint8([<span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">])
      </span>&gt;&gt;&gt; print cv2.add(x,y) # <span style="color: rgba(128, 0, 128, 1)">250</span>+<span style="color: rgba(128, 0, 128, 1)">10</span> = <span style="color: rgba(128, 0, 128, 1)">260</span> =&gt; <span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">#相加,opencv超过255的截取为255
      [[</span><span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">]]
      </span>&gt;&gt;&gt; print x+y          # <span style="color: rgba(128, 0, 128, 1)">250</span>+<span style="color: rgba(128, 0, 128, 1)">10</span> = <span style="color: rgba(128, 0, 128, 1)">260</span> % <span style="color: rgba(128, 0, 128, 1)">256</span> = <span style="color: rgba(128, 0, 128, 1)">4</span>#相加,np超过255的会取模运算 (uint8只能表示0-<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,所以取模)
      [</span><span style="color: rgba(128, 0, 128, 1)">4</span>]</pre>
</div>
<p>      使用示例:图一无掩膜,图二有掩膜</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_54d9a4a9-6b59-4f32-a49b-50fc7b092aca" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_54d9a4a9-6b59-4f32-a49b-50fc7b092aca" class="cnblogs_code_hide">
<pre>#coding:utf-<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">


import cv2 </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> cv
import numpy </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> np
img1 </span>= cv.imread(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\cat.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
roi_img</span>= np.zeros(img1.shape[<span style="color: rgba(128, 0, 128, 1)">0</span>:<span style="color: rgba(128, 0, 128, 1)">2</span>],dtype=<span style="color: rgba(0, 0, 0, 1)">np.uint8)
# print(img1.shape[</span><span style="color: rgba(128, 0, 128, 1)">0</span>:<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">])
roi_img[</span><span style="color: rgba(128, 0, 128, 1)">100</span>:<span style="color: rgba(128, 0, 128, 1)">280</span>,<span style="color: rgba(128, 0, 128, 1)">400</span>:<span style="color: rgba(128, 0, 128, 1)">550</span>]=<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">

img_add </span>=<span style="color: rgba(0, 0, 0, 1)"> cv.add(img1,img1)
img_add_mask </span>= cv.add(img1,img1,mask=<span style="color: rgba(0, 0, 0, 1)">roi_img)
# cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img1)
# cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">roi_img</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,roi_img)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img_add</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img_add)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img_add_mask</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img_add_mask)

cv.waitKey(</span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
cv.destroyAllWindows()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>      <img alt="" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601141536082-1019705943.png"></p>
<p>  </p>
<p>      <img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601141609497-107446803.png"></p>
<p>      cv.addWeight():&nbsp;两张图片相加,分别给予不同权重,实现图片融合和透明背景等效果</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.addWeighted() 两张图片相加,分别给予不同权重,实现图片融合和透明背景等效果
    参数:
      img1:图片对象1
      alpha:img1的权重
      img2:图片对象2
      beta:img1的权重
      gamma:常量值,图像相加后再加上常量值
      dtype:返回图像的数据类型,默认为</span>-<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">,和img1一样
    (img1</span>*alpha+img2*beta+gamma)</pre>
</div>
<p>    使用示例:</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_cbff0068-52cb-4140-9a58-96f714e7e8f9" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_cbff0068-52cb-4140-9a58-96f714e7e8f9" class="cnblogs_code_hide">
<pre>#coding:utf-<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">

import cv2 </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> cv

img1 </span>= cv.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\dog.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
img </span>= img1[<span style="color: rgba(128, 0, 128, 1)">0</span>:<span style="color: rgba(128, 0, 128, 1)">426</span>,<span style="color: rgba(128, 0, 128, 1)">43</span>:<span style="color: rgba(128, 0, 128, 1)">683</span><span style="color: rgba(0, 0, 0, 1)">]
img2 </span>= cv.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\cat.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

blend </span>= cv.addWeighted(img,<span style="color: rgba(128, 0, 128, 1)">0.5</span>,img2,<span style="color: rgba(128, 0, 128, 1)">0.9</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)#两张图的大小和通道也应该相同

cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">blend</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,blend)
cv.waitKey()
cv.destroyAllWindows()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>    <img alt="" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601143333535-439856475.png"></p>
<p><span style="font-size: 16px"><strong>  2.6 图像位运算</strong></span></p>
<p>     <span style="color: rgba(0, 0, 0, 1)">btwise_and(), bitwise_or(), bitwise_not(), bitwise_xor()</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.btwise_and(): 与运算
    参数:
      img1:图片对象1
      img2:图片对象2
      mask:掩膜
    cv2.bitwise_or():或运算
    参数:
      img1:图片对象1
      img2:图片对象2
      mask:掩膜
    cv2.bitwise_not(): 非运算
      img1:图片对象1
      mask:掩膜
    cv2.bitwise_xor():异或运算,相同为1,不同为0(</span><span style="color: rgba(128, 0, 128, 1)">1</span>^<span style="color: rgba(128, 0, 128, 1)">1</span>=<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">1</span>^<span style="color: rgba(128, 0, 128, 1)">0</span>=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
      img1:图片对象1
      img2:图片对象2
      mask:掩膜</span></pre>
</div>
<p>  使用示例:将logo图片移动到足球图片中,需要截取logo图片的前景和足球图片ROI的背景,然后叠加,效果如下:</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_ff2b6773-e214-4772-a27c-df0d62a15487" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_ff2b6773-e214-4772-a27c-df0d62a15487" class="cnblogs_code_hide">
<pre>#coding:utf-<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">


import cv2 </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> cv
import matplotlib.pyplot </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> plt

img1 </span>= cv.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\logo.png</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
rows,cols </span>= img1.shape[<span style="color: rgba(128, 0, 128, 1)">0</span>:<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">]
img2 </span>= cv.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\Messi.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
roi </span>= img2[<span style="color: rgba(128, 0, 128, 1)">0</span>:rows,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">:cols]
img1_gray </span>=<span style="color: rgba(0, 0, 0, 1)"> cv.cvtColor(img1,cv.COLOR_BGR2GRAY)

ret,img1_thres </span>= cv.threshold(img1_gray,<span style="color: rgba(128, 0, 128, 1)">200</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,cv.THRESH_BINARY_INV)
img1_fg </span>=cv.add(img1,img1,mask=<span style="color: rgba(0, 0, 0, 1)">img1_thres)    #拿到logo图案的前景

img1_thres_inv </span>=<span style="color: rgba(0, 0, 0, 1)"> cv.bitwise_not(img1_thres)
roi_bg </span>= cv.add(roi,roi,mask=<span style="color: rgba(0, 0, 0, 1)">img1_thres_inv)#拿到roi图案的背景

img_add </span>=<span style="color: rgba(0, 0, 0, 1)"> cv.add(img1_fg,roi_bg)   #背景和前景相加   
img2[</span><span style="color: rgba(128, 0, 128, 1)">0</span>:rows,<span style="color: rgba(128, 0, 128, 1)">0</span>:cols] =<span style="color: rgba(0, 0, 0, 1)"> img_add

cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">gray</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img1_gray)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">thres</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img1_thres)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img1_fg)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tinv</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img1_thres_inv)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">roi_bg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,roi_bg)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img_add</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img_add)
cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img2)
cv.waitKey(</span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
cv.destroyAllWindows()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><img alt="" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601161550607-2134006672.png"></p>
<p><span style="font-size: 16px"><strong>  2.7 图像颜色空间转换</strong></span></p>
<p>    cv2.cvtColor()</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.cvtColor()
    参数:
      img: 图像对象
      code:
            cv2.COLOR_RGB2GRAY: RGB转换到灰度模式
            cv2.COLOR_RGB2HSV: RGB转换到HSV模式(hue,saturation,Value)
cv2.inRange()
    参数:
      img: 图像对象</span>/<span style="color: rgba(0, 0, 0, 1)">array
      lowerb: 低边界array,如lower_blue </span>= np.array([<span style="color: rgba(128, 0, 128, 1)">110</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>,<span style="color: rgba(128, 0, 128, 1)">50</span><span style="color: rgba(0, 0, 0, 1)">])
      upperb:高边界array, 如 upper_blue </span>= np.array([<span style="color: rgba(128, 0, 128, 1)">130</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">])
    mask </span>= cv2.inRange(hsv, lower_green, upper_green)</pre>
</div>
<p><span style="font-size: 16px"> <strong> 2.8 性能评价 </strong></span></p>
<p>   cv2.getTickCount(): 获得时钟次数</p>
<p>   <span style="color: rgba(0, 0, 0, 1)">cv2.getTickFrequency()</span>:获得时钟频率 (每秒振动次数)</p>
<div class="cnblogs_code">
<pre>img1 = cv2.imread(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">messi5.jpg</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)

e1 </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.getTickCount()
</span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> xrange(<span style="color: rgba(128, 0, 128, 1)">5</span>,<span style="color: rgba(128, 0, 128, 1)">49</span>,<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">):
    img1 </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.medianBlur(img1,i)
e2 </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.getTickCount()
t </span>= (e2 - e1)/<span style="color: rgba(0, 0, 0, 1)">cv2.getTickFrequency()
print t</span></pre>
</div>
<p>&nbsp;<strong><span style="font-size: 16px">  2.9 绑定trackbar到图像</span></strong></p>
<p>    cv2.createTrackbar()</p>
<p>    cv2.getTrackbarPos()</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">    cv2.createTrackbar() 为窗口添加trackbar
    参数:
      trackbarname: trackbar的名字
      winname: 窗口的名字
      value: trackbar创建时的值
      count:trackbar能设置的最大值,最小值总为0
      onChange:trackbar值发生变化时的回调函数,trackbar的值作为参数传给onchange
      
    cv2.getTrackbarPos() 获取某个窗口中trackbar的值
    参数:
      trackbarname: trackbar的名字
      winname: 窗口的名字</span></pre>
</div>
<p>    使用示例:通过改变trackbar的值,来寻找最优的mask范围,从而识别出图片中蓝色的瓶盖</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_48530925-6cb7-4cf3-aff2-188b4837c0df" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_48530925-6cb7-4cf3-aff2-188b4837c0df" class="cnblogs_code_hide">
<pre>#coding:utf-<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">

import cv2 </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> cv
import numpy </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> np

def nothing(args):
    pass

img </span>= cv.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\frame.png</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
img_hsv </span>=<span style="color: rgba(0, 0, 0, 1)"> cv.cvtColor(img,cv.COLOR_BGR2HSV)
cv.namedWindow(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
cv.createTrackbar(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LH</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,nothing)
cv.createTrackbar(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LS</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,nothing)
cv.createTrackbar(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LV</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,nothing)

cv.createTrackbar(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UH</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,nothing)
cv.createTrackbar(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">US</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,nothing)
cv.createTrackbar(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UV</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,nothing)

# </span><span style="color: rgba(0, 0, 255, 1)">switch</span> = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0:OFF \n1:ON</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
# cv.createTrackbar(</span><span style="color: rgba(0, 0, 255, 1)">switch</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">,nothing)


</span><span style="color: rgba(0, 0, 255, 1)">while</span>(<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">):
      
    l_h </span>= cv.getTrackbarPos(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LH</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    l_s </span>= cv.getTrackbarPos(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LS</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    l_v </span>= cv.getTrackbarPos(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LV</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    u_h </span>= cv.getTrackbarPos(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UH</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    u_s </span>= cv.getTrackbarPos(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">US</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    u_v </span>= cv.getTrackbarPos(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UV</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tracks</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
   
    lower_b </span>=<span style="color: rgba(0, 0, 0, 1)"> np.array()
    upper_b </span>=<span style="color: rgba(0, 0, 0, 1)"> np.array()
   
    mask </span>=<span style="color: rgba(0, 0, 0, 1)"> cv.inRange(img_hsv,lower_b,upper_b)
    res </span>= cv.add(img,img,mask=<span style="color: rgba(0, 0, 0, 1)">mask)
   
    cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,img)
    cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mask</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,mask)
    cv.imshow(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">res</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,res)
    k </span>= cv.waitKey(<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> k==<span style="color: rgba(128, 0, 128, 1)">27</span><span style="color: rgba(0, 0, 0, 1)">:
      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">
   
   
    # print(r,g,b)
    # </span><span style="color: rgba(0, 0, 255, 1)">if</span> s==<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">:
      # img[:]</span>=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
    # </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
      # img[:]</span>=<span style="color: rgba(0, 0, 0, 1)">




cv.destroyAllWindows()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>      <img alt="" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601191315454-2089153172.png"></p>
<p>&nbsp;</p>
<p>   <img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601190419060-1506057737.png"></p>
<p><span style="font-size: 18px"><strong>3. 图像阈值化</strong></span></p>
<p>  cv2.threshold()</p>
<p>  cv2.adaptiveThreshold()</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.threshold():
参数:
    img:图像对象,必须是灰度图
    thresh:阈值
    maxval:最大值
    type:
      cv2.THRESH_BINARY:   小于阈值的像素置为0,大于阈值的置为maxval
      cv2.THRESH_BINARY_INV: 小于阈值的像素置为maxval,大于阈值的置为0
      cv2.THRESH_TRUNC:      小于阈值的像素不变,大于阈值的置为thresh
      cv2.THRESH_TOZERO       小于阈值的像素置0,大于阈值的不变
      cv2.THRESH_TOZERO_INV   小于阈值的不变,大于阈值的像素置0
返回两个值
    ret:阈值
    img:阈值化处理后的图像
   
cv2.adaptiveThreshold() 自适应阈值处理,图像不同部位采用不同的阈值进行处理
参数:
    img: 图像对象,</span><span style="color: rgba(128, 0, 128, 1)">8</span>-<span style="color: rgba(0, 0, 0, 1)">bit单通道图
    maxValue:最大值
    adaptiveMethod: 自适应方法
      cv2.ADAPTIVE_THRESH_MEAN_C   :阈值为周围像素的平均值
      cv2.ADAPTIVE_THRESH_GAUSSIAN_C : 阈值为周围像素的高斯均值(按权重)
    threshType:
      cv2.THRESH_BINARY:   小于阈值的像素置为0,大于阈值的置为maxValuel
      cv2.THRESH_BINARY_INV:小于阈值的像素置为maxValue,大于阈值的置为0
    blocksize: 计算阈值时,自适应的窗口大小,必须为奇数 (如3:表示附近3个像素范围内的像素点,进行计算阈值)
    C: 常数值,通过自适应方法计算的值,减去该常数值
(mean value of the blocksize</span>*blocksize neighborhood of (x, y) minus C)</pre>
</div>
<p>  使用示例:</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_9f7bb581-d1c1-4d9a-800c-1845659f62d5" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_9f7bb581-d1c1-4d9a-800c-1845659f62d5" class="cnblogs_code_hide">
<pre>#coding:utf-<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">

import cv2 </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> cv
import matplotlib.pyplot </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> plt

img </span>= cv.imread(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C:\Users\Administrator\Desktop\maze.png</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)

ret,thre1 </span>= cv.threshold(img,<span style="color: rgba(128, 0, 128, 1)">127</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,cv.THRESH_BINARY)
adaptive_thre1 </span>= cv.adaptiveThreshold(img,<span style="color: rgba(128, 0, 128, 1)">255</span>,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,<span style="color: rgba(128, 0, 128, 1)">7</span>,<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">)
adaptive_thre2 </span>= cv.adaptiveThreshold(img,<span style="color: rgba(128, 0, 128, 1)">255</span>,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,<span style="color: rgba(128, 0, 128, 1)">7</span>,<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">)

titles </span>= [<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">thre1</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">adaptive_thre1</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">adaptive_thre2</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]
imgs </span>=<span style="color: rgba(0, 0, 0, 1)">

</span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> range(<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">):
    plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">2</span>,<span style="color: rgba(128, 0, 128, 1)">2</span>,i+<span style="color: rgba(128, 0, 128, 1)">1</span>), plt.imshow(imgs,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">gray</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    plt.title(titles)
    plt.xticks([]),plt.yticks([])
plt.show()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>    <img alt="" style="display: block; margin-left: auto; margin-right: auto" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601224018337-495239331.png"></p>
<p> <strong> 奥斯二值化(Otsu's Binarization)</strong></p>
<p>    对于一些双峰图像,奥斯二值化能找到两峰之间的像素值作为阈值,并将其返回。适用于双峰图像的阈值化,或者通过去噪而产生的双峰图像。</p>
<p>    官网使用示例:</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_01a2197b-079d-4fbf-bf7d-a0ae69de2299" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_01a2197b-079d-4fbf-bf7d-a0ae69de2299" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">import cv2
import numpy </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> np
</span><span style="color: rgba(0, 0, 255, 1)">from</span> matplotlib import pyplot <span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> plt

img </span>= cv2.imread(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">noisy2.png</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)

# </span><span style="color: rgba(0, 0, 255, 1)">global</span><span style="color: rgba(0, 0, 0, 1)"> thresholding
ret1,th1 </span>= cv2.threshold(img,<span style="color: rgba(128, 0, 128, 1)">127</span>,<span style="color: rgba(128, 0, 128, 1)">255</span><span style="color: rgba(0, 0, 0, 1)">,cv2.THRESH_BINARY)

# Otsu</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">s thresholding</span>
ret2,th2 = cv2.threshold(img,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,cv2.THRESH_BINARY+<span style="color: rgba(0, 0, 0, 1)">cv2.THRESH_OTSU)

# Otsu</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">s thresholding after Gaussian filtering</span>
blur = cv2.GaussianBlur(img,(<span style="color: rgba(128, 0, 128, 1)">5</span>,<span style="color: rgba(128, 0, 128, 1)">5</span>),<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
ret3,th3 </span>= cv2.threshold(blur,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">255</span>,cv2.THRESH_BINARY+<span style="color: rgba(0, 0, 0, 1)">cv2.THRESH_OTSU)

# plot all the images and their histograms
images </span>= [img, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, th1,
          img, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, th2,
          blur, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, th3]
titles </span>= [<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Original Noisy Image</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Histogram</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Global Thresholding (v=127)</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
          </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Original Noisy Image</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Histogram</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Otsu's Thresholding</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
          </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Gaussian filtered Image</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Histogram</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Otsu's Thresholding</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]

</span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> xrange(<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">):
    plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">3</span>,<span style="color: rgba(128, 0, 128, 1)">3</span>,i*<span style="color: rgba(128, 0, 128, 1)">3</span>+<span style="color: rgba(128, 0, 128, 1)">1</span>),plt.imshow(images,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">gray</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    plt.title(titles), plt.xticks([]), plt.yticks([])
    plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">3</span>,<span style="color: rgba(128, 0, 128, 1)">3</span>,i*<span style="color: rgba(128, 0, 128, 1)">3</span>+<span style="color: rgba(128, 0, 128, 1)">2</span>),plt.hist(images.ravel(),<span style="color: rgba(128, 0, 128, 1)">256</span><span style="color: rgba(0, 0, 0, 1)">)
    plt.title(titles), plt.xticks([]), plt.yticks([])
    plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">3</span>,<span style="color: rgba(128, 0, 128, 1)">3</span>,i*<span style="color: rgba(128, 0, 128, 1)">3</span>+<span style="color: rgba(128, 0, 128, 1)">3</span>),plt.imshow(images,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">gray</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    plt.title(titles), plt.xticks([]), plt.yticks([])
plt.show()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span>   <img alt="" style="display: block; margin-left: auto; margin-right: auto" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190601224852098-1757221396.png"></div>
<p>&nbsp;</p>
<p><span style="font-size: 18px"><strong>4. 图像形状变换</strong></span></p>
<p>  <span style="font-size: 16px"><strong>4.1 cv2.resize()&nbsp;&nbsp; 图像缩放</strong></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.resize() 放大和缩小图像
    参数:
      src: 输入图像对象
      dsize:输出矩阵</span>/图像的大小,为0时计算方式如下:dsize = Size(round(fx*src.cols),round(fy*<span style="color: rgba(0, 0, 0, 1)">src.rows))
      fx: 水平轴的缩放因子,为0时计算方式:(</span><span style="color: rgba(0, 0, 255, 1)">double</span>)dsize.width/<span style="color: rgba(0, 0, 0, 1)">src.cols
      fy: 垂直轴的缩放因子,为0时计算方式:(</span><span style="color: rgba(0, 0, 255, 1)">double</span>)dsize.heigh/<span style="color: rgba(0, 0, 0, 1)">src.rows
      interpolation:插值算法
            cv2.INTER_NEAREST : 最近邻插值法
            cv2.INTER_LINEAR   默认值,双线性插值法
            cv2.INTER_AREA      基于局部像素的重采样(resampling </span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。
            cv2.INTER_CUBIC      基于4x4像素邻域的3次插值法
            cv2.INTER_LANCZOS4   基于8x8像素邻域的Lanczos插值
                     
    cv2.INTER_AREA 适合于图像缩小, cv2.INTER_CUBIC (slow) </span>&amp; cv2.INTER_LINEAR 适合于图像放大</pre>
</div>
<p>    官网示例:</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_a7c25570-c9d0-4617-bbdf-d755f78f9bd3" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_a7c25570-c9d0-4617-bbdf-d755f78f9bd3" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">import cv2
import numpy </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> np

img </span>= cv2.imread(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">messi5.jpg</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)

res </span>= cv2.resize(img,None,fx=<span style="color: rgba(128, 0, 128, 1)">2</span>, fy=<span style="color: rgba(128, 0, 128, 1)">2</span>, interpolation =<span style="color: rgba(0, 0, 0, 1)"> cv2.INTER_CUBIC)

#OR

height, width </span>= img.shape[:<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">]
res </span>= cv2.resize(img,(<span style="color: rgba(128, 0, 128, 1)">2</span>*width, <span style="color: rgba(128, 0, 128, 1)">2</span>*height), interpolation = cv2.INTER_CUBIC)</pre>
</div>
<span class="cnblogs_code_collapse">图像放大两倍</span></div>
<p>  <strong><span style="font-size: 16px">4.2 cv2.warpAffine()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;仿射变换</span></strong></p>
<p>     仿射变换(从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.warpAffine()   仿射变换(从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切)
    参数:
      img: 图像对象
      M:</span><span style="color: rgba(128, 0, 128, 1)">2</span>*<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)"> transformation matrix (转变矩阵)
      dsize:输出矩阵的大小,注意格式为(cols,rows)即width对应cols,height对应rows
      flags:可选,插值算法标识符,有默认值INTER_LINEAR,
               如果插值算法为WARP_INVERSE_MAP, warpAffine函数使用如下矩阵进行图像转dst(x,y)</span>=src(M11*x+M12*y+M13,M21*x+M22*y+<span style="color: rgba(0, 0, 0, 1)">M23)
      borderMode:可选, 边界像素模式,有默认值BORDER_CONSTANT
      borderValue:可选,边界取值,有默认值Scalar()即0</span></pre>
</div>
<p>     常用插值算法:</p>
<p><img alt="" style="display: block; margin-left: auto; margin-right: auto" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190602091005036-227493627.png"></p>
<p>   仿射变换的本质:即一个矩阵A和向量B共同组成的转变矩阵,和原图像坐标相乘来得到新图像的坐标,从而实现图像移动,旋转等。如下矩阵A和向量B组成的转变矩阵M,用来对原图像的坐标(x,y)进行转变,得到新的坐标向量T</p>
<p>    矩阵A和向量B</p>
<p><img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190602092346111-65750210.png"></p>
<p>    仿射变换(矩阵计算):变换前坐标(x,y)</p>
<p><img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190602092700612-1331464134.png"></p>
<p>    变换结果:变换后坐标(a00*x+a01 *y+b00, a10*x+a11*y+b10)</p>
<p><img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190602092727342-320819378.png"></p>
<p><strong><span style="font-size: 15px">  4.2.1 平移变换</span></strong></p>
<p>    了解了仿射变换的概念,平移变换只是采用了一个如下的转变矩阵(transformation matrix): 从(x,y)平移到(x+t<sub>x</sub>, y+t<sub>y</sub>)</p>
<p>                  <img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190607095256206-1049501258.png"></p>
<p>           <img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190607101003221-1123704351.png"></p>
<p>     官网使用示例:向右平移100,向下平移50</p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_74aa4e6f-8303-4422-8ef6-e32563e4cfdd" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_74aa4e6f-8303-4422-8ef6-e32563e4cfdd" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">import cv2
import numpy </span><span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> np

img </span>= cv2.imread(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">messi5.jpg</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
rows,cols </span>=<span style="color: rgba(0, 0, 0, 1)"> img.shape

M </span>= np.float32([[<span style="color: rgba(128, 0, 128, 1)">1</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>],[<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">1</span>,<span style="color: rgba(128, 0, 128, 1)">50</span><span style="color: rgba(0, 0, 0, 1)">]])
dst </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.warpAffine(img,M,(cols,rows))

cv2.imshow(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,dst)
cv2.waitKey(</span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
cv2.destroyAllWindows()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>  <span style="font-size: 15px"><strong>4.2.2 放大和缩小</strong></span></p>
<p>     放大和缩小指相对于原坐标(x,y),变换为了(a*x, b*y),即水平方向放大了a倍,水平方向放大了b倍,其对应的转变矩阵如下:</p>
<p>            <img alt="" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190607111439230-653546455.png"></p>
<p>  <span style="font-size: 15px"><strong>4.2.3 旋转变换</strong></span></p>
<p>      将(x,y),以坐标原点为中心,顺时针方向旋转α得到(x<sub>1,</sub>y<sub>1</sub>), 有如下关系x<sub>1</sub> = xcosα-ysinα, y<sub>1</sub> =xsinα+ycosα; 因此可以构建对应的转变矩阵如下:<img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190607104028901-605422183.png"></p>
<p>      opencv将其扩展到,任意点center为中心进行顺时针旋转α,放大scale倍的,转变矩阵如下:</p>
<p>            <img src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190607104933761-1590038994.png"></p>
<p>&nbsp;      通过getRotationMatrix2D()能得到转变矩阵</p>
<div class="cnblogs_code">
<pre>  cv2.getRotationMatrix2D()返回2*<span style="color: rgba(0, 0, 0, 1)">3的转变矩阵(浮点型)
    参数:
      center:旋转的中心点坐标
      angle:旋转角度,单位为度数,证书表示逆时针旋转
      scale:同方向的放大倍数</span></pre>
</div>
<p>  <span style="font-size: 15px"><strong>4.2.4 仿射变换矩阵的计算</strong></span></p>
<p>    通过上述的平移,缩放,旋转的组合变换即实现了仿射变换,上述多个变换的变换矩阵相乘即能得到组合变换的变换矩阵。同时该变换矩阵中涉及到六个未知数(2*3的矩阵),通过变换前后对应三组坐标,也可以求出变换矩阵,opencv提供了函数getAffineTransform()来计算变化矩阵</p>
<p>    1&gt; 矩阵相乘:将平移,旋转和缩放的变换矩阵相乘,最后即为仿射变换矩阵</p>
<p>    2&gt;&nbsp;getAffineTransform():根据变换前后三组坐标计算变换矩阵     </p>
<div class="cnblogs_code">
<pre>    cv2.getAffineTransform()返回2*<span style="color: rgba(0, 0, 0, 1)">3的转变矩阵
      参数:
          src:原图像中的三组坐标,如np.float32([[</span><span style="color: rgba(128, 0, 128, 1)">50</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>],[<span style="color: rgba(128, 0, 128, 1)">200</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>],[<span style="color: rgba(128, 0, 128, 1)">50</span>,<span style="color: rgba(128, 0, 128, 1)">200</span><span style="color: rgba(0, 0, 0, 1)">]])
        dst: 转换后的对应三组坐标,如np.float32([[</span><span style="color: rgba(128, 0, 128, 1)">10</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>],[<span style="color: rgba(128, 0, 128, 1)">200</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>],[<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">250</span>]])</pre>
</div>
<p>    官网使用示例:     </p>
<div class="cnblogs_code"><img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_fd7dee36-339f-4d5c-a43a-cd9d7c62bf16" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_fd7dee36-339f-4d5c-a43a-cd9d7c62bf16" class="cnblogs_code_hide">
<pre>img = cv2.imread(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">drawing.png</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
rows,cols,ch </span>=<span style="color: rgba(0, 0, 0, 1)"> img.shape

pts1 </span>= np.float32([[<span style="color: rgba(128, 0, 128, 1)">50</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>],[<span style="color: rgba(128, 0, 128, 1)">200</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>],[<span style="color: rgba(128, 0, 128, 1)">50</span>,<span style="color: rgba(128, 0, 128, 1)">200</span><span style="color: rgba(0, 0, 0, 1)">]])
pts2 </span>= np.float32([[<span style="color: rgba(128, 0, 128, 1)">10</span>,<span style="color: rgba(128, 0, 128, 1)">100</span>],[<span style="color: rgba(128, 0, 128, 1)">200</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>],[<span style="color: rgba(128, 0, 128, 1)">100</span>,<span style="color: rgba(128, 0, 128, 1)">250</span><span style="color: rgba(0, 0, 0, 1)">]])

M </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.getAffineTransform(pts1,pts2)

dst </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.warpAffine(img,M,(cols,rows))

plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">121</span>),plt.imshow(img),plt.title(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Input</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">122</span>),plt.imshow(dst),plt.title(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Output</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
plt.show()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><span style="font-size: 16px">  <strong>4.3 透视变换(persperctive transformation)</strong></span></p>
<p>    仿射变换都是在二维空间的变换,透视变换(投影变换)是在三维空间中发生了旋转。需要前后四组坐标来计算对应的转变矩阵,opencv提供了函数getPerspectiveTransform()来计算转变矩阵,cv2.warpPerspective()函数来进行透视变换。其对应参数如下: </p>
<div class="cnblogs_code">
<pre>     cv2.getPerspectiveTransform()   返回3*<span style="color: rgba(0, 0, 0, 1)">3的转变矩阵
      参数:   
            src:原图像中的四组坐标,如 np.float32([[</span><span style="color: rgba(128, 0, 128, 1)">56</span>,<span style="color: rgba(128, 0, 128, 1)">65</span>],[<span style="color: rgba(128, 0, 128, 1)">368</span>,<span style="color: rgba(128, 0, 128, 1)">52</span>],[<span style="color: rgba(128, 0, 128, 1)">28</span>,<span style="color: rgba(128, 0, 128, 1)">387</span>],[<span style="color: rgba(128, 0, 128, 1)">389</span>,<span style="color: rgba(128, 0, 128, 1)">390</span><span style="color: rgba(0, 0, 0, 1)">]])
            dst: 转换后的对应四组坐标,如np.float32([[</span><span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>],[<span style="color: rgba(128, 0, 128, 1)">300</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>],[<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">300</span>],[<span style="color: rgba(128, 0, 128, 1)">300</span>,<span style="color: rgba(128, 0, 128, 1)">300</span><span style="color: rgba(0, 0, 0, 1)">]])

            
      cv2.warpPerspective()
      参数:   
            src: 图像对象
            M:</span><span style="color: rgba(128, 0, 128, 1)">3</span>*<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)"> transformation matrix (转变矩阵)
            dsize:输出矩阵的大小,注意格式为(cols,rows)即width对应cols,height对应rows
            flags:可选,插值算法标识符,有默认值INTER_LINEAR,
                   如果插值算法为WARP_INVERSE_MAP, warpAffine函数使用如下矩阵进行图像转dst(x,y)</span>=src(M11*x+M12*y+M13,M21*x+M22*y+<span style="color: rgba(0, 0, 0, 1)">M23)
            borderMode:可选, 边界像素模式,有默认值BORDER_CONSTANT
            borderValue:可选,边界取值,有默认值Scalar()即0</span></pre>
</div>
<p>   官网使用示例:</p>
<div class="cnblogs_code"><img alt="" id="code_img_closed_dc3a9e73-cf2d-42a2-8def-a751878e0389" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img alt="" id="code_img_opened_dc3a9e73-cf2d-42a2-8def-a751878e0389" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_dc3a9e73-cf2d-42a2-8def-a751878e0389" class="cnblogs_code_hide">
<pre>img = cv2.imread(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">sudokusmall.png</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
rows,cols,ch </span>=<span style="color: rgba(0, 0, 0, 1)"> img.shape

pts1 </span>= np.float32([[<span style="color: rgba(128, 0, 128, 1)">56</span>,<span style="color: rgba(128, 0, 128, 1)">65</span>],[<span style="color: rgba(128, 0, 128, 1)">368</span>,<span style="color: rgba(128, 0, 128, 1)">52</span>],[<span style="color: rgba(128, 0, 128, 1)">28</span>,<span style="color: rgba(128, 0, 128, 1)">387</span>],[<span style="color: rgba(128, 0, 128, 1)">389</span>,<span style="color: rgba(128, 0, 128, 1)">390</span><span style="color: rgba(0, 0, 0, 1)">]])
pts2 </span>= np.float32([[<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>],[<span style="color: rgba(128, 0, 128, 1)">300</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>],[<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">300</span>],[<span style="color: rgba(128, 0, 128, 1)">300</span>,<span style="color: rgba(128, 0, 128, 1)">300</span><span style="color: rgba(0, 0, 0, 1)">]])

M </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.getPerspectiveTransform(pts1,pts2)

dst </span>= cv2.warpPerspective(img,M,(<span style="color: rgba(128, 0, 128, 1)">300</span>,<span style="color: rgba(128, 0, 128, 1)">300</span><span style="color: rgba(0, 0, 0, 1)">))

plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">121</span>),plt.imshow(img),plt.title(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Input</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
plt.subplot(</span><span style="color: rgba(128, 0, 128, 1)">122</span>),plt.imshow(dst),plt.title(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Output</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
plt.show()</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>      <img alt="" data-src="https://img2018.cnblogs.com/blog/1483773/201906/1483773-20190607114939954-1993012118.png"></p>
<p>   从上图中可以透视变换的一个应用,如果能找到原图中纸张的四个顶点,将其转换到新图中纸张的四个顶点,能将歪斜的roi区域转正,并进行放大;如在书籍,名片拍照上传后进行识别时,是一个很好的图片预处理方法。</p>
<p>&nbsp;   opencv中还提供了一个函数perspctiveTransform()来对坐标点进行透视变换,对于原图像上的一点,通过perspctiveTransform()能计算出透视变换后图片上该点的坐标,其对应参数如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cv2.perspectiveTransform(src, matrix)

参数:
    src:坐标点矩阵,注意其格式. 如src=</span>np.array([,,,], np.float32).reshape(-1, 1, 2), 表示四个坐标点,size为(4, -1, 2)</pre>
<pre><span style="color: rgba(0, 0, 0, 1)">    matrix:getPerspectiveTransform()得到的透视变换矩阵 返回值:变换后的坐标点,格式和src相同</span></pre>
</div>
<p>  若变换前坐标点src(x, y),变换后坐标点为dst(X, Y), 其内部计算过程如下</p>
<p><img src="https://img2020.cnblogs.com/blog/1483773/202102/1483773-20210210175616751-623661270.png"></p>
<p>&nbsp;</p>
<p>&nbsp;  </p>
<div class="cnblogs_code"><img id="code_img_closed_a2c3fd75-3b41-42c6-b856-e0328a70ed28" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_a2c3fd75-3b41-42c6-b856-e0328a70ed28" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_a2c3fd75-3b41-42c6-b856-e0328a70ed28" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">#matrix
matrix </span>= np.float32([[ <span style="color: rgba(128, 0, 128, 1)">8.06350904e-01</span> -<span style="color: rgba(128, 0, 128, 1)">1.67497791e-02</span> -<span style="color: rgba(128, 0, 128, 1)">4.34096149e+01</span><span style="color: rgba(0, 0, 0, 1)">]
[ </span><span style="color: rgba(128, 0, 128, 1)">2.85178118e-02</span><span style="color: rgba(128, 0, 128, 1)">8.29440456e-01</span> -<span style="color: rgba(128, 0, 128, 1)">6.26063898e+01</span><span style="color: rgba(0, 0, 0, 1)">]
[ </span><span style="color: rgba(128, 0, 128, 1)">2.41877972e-05</span><span style="color: rgba(128, 0, 128, 1)">1.99790270e-05</span><span style="color: rgba(128, 0, 128, 1)">1.00000000e+00</span><span style="color: rgba(0, 0, 0, 1)">]])

rect </span>= np.array([[<span style="color: rgba(128, 0, 128, 1)">589</span>, <span style="color: rgba(128, 0, 128, 1)">91</span>], [<span style="color: rgba(128, 0, 128, 1)">1355</span>, <span style="color: rgba(128, 0, 128, 1)">91</span>], [<span style="color: rgba(128, 0, 128, 1)">1355</span>, <span style="color: rgba(128, 0, 128, 1)">219</span>], [<span style="color: rgba(128, 0, 128, 1)">589</span>, <span style="color: rgba(128, 0, 128, 1)">219</span><span style="color: rgba(0, 0, 0, 1)">]], np.float32)
rect </span>= rect.reshape(-<span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">)
newRect </span>=<span style="color: rgba(0, 0, 0, 1)"> cv2.perspectiveTransform(rect, matrix)



def test(rect, matrix):
    rect_fill </span>= np.ones((<span style="color: rgba(128, 0, 128, 1)">4</span>, <span style="color: rgba(128, 0, 128, 1)">3</span>), dtype=<span style="color: rgba(0, 0, 0, 1)">np.float32)
    rect_fill[:, :</span><span style="color: rgba(128, 0, 128, 1)">2</span>] =<span style="color: rgba(0, 0, 0, 1)"> rect
    mid_rect </span>=<span style="color: rgba(0, 0, 0, 1)"> np.dot(matrix, rect_fill.T)
    mid_rect </span>=<span style="color: rgba(0, 0, 0, 1)"> mid_rect.T
    mid_rect[:, :</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = mid_rect[:, :<span style="color: rgba(128, 0, 128, 1)">2</span>]/mid_rect[:, <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">:]
    print(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TEST</span><span style="color: rgba(128, 0, 0, 1)">"</span>, mid_rect)</pre>
</div>
<span class="cnblogs_code_collapse">perspectiveTransform</span></div>
<p>&nbsp;官方文档:https://docs.opencv.org/3.0-beta/modules/imgproc/doc/miscellaneous_transformations.html?highlight=adaptivethreshold#cv2.adaptiveThreshold</p>
<p>&nbsp;Tutorial:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_trackbar/py_trackbar.html#trackbar</p><br><br>
来源:https://www.cnblogs.com/silence-cho/p/10926248.html
頁: [1]
查看完整版本: (一)OpenCV-Python学习—基础知识