2.1 OpenCV隨手簡記(二)

為后續項目學習做準備,我們需要了解LinuxOpenCV、Mediapipe、ROS、QT等知識。

一、圖像顯示與保存

1、基本原理

1.1 圖像像素存儲形式

首先得了解下圖像在計算機中存儲形式:(為了方便畫圖,每列像素值都寫一樣了)。對于只有黑白顏色的灰度圖,為單通道,一個像素塊對應矩陣中一個數字,數值為0到255, 其中0表示最暗(黑色) ,255表示最亮(白色)

對于采用RGB模式的彩色圖片,為三通道圖,Red、Green、Blue三原色,按不同比例相加,一個像素塊對應矩陣中的一個向量, 如[24,180, 50],分別表示三種顏色的比列, 即對應深度上的數字,如下圖所示:

?需要注意的是,由于歷史遺留問題,opencv采用BGR模式,而不是RGB


2、API說明

API名: cv2.destroyAllWindows( )

刪除所有我們建立的窗口

API名:?cv2.destroyWindow(指定窗口名)

刪除特定的窗口可以使用,在括號內輸入你想刪?除的窗口名。

API名: cv2.imshow('窗口名', 圖像變量):

用“窗口名”顯示圖像

API名:cv2.resizeWindow(‘窗口名’, 寬, 高) ?

調整窗口大小

API名:cv2.imwrite('圖像文件地址',圖像變量)

將圖像變量保存到指定位置的指定文件中

?API名:cv.namedWindow(winname, flags=None)

參數:winname

窗口名字

flags窗口標志

標志參數

作用

WINDOW_NORMAL

顯示圖像后,允許用戶隨意調整窗口大小

WINDOW_AUTOSIZE

根據圖像大小顯示窗口,不允許用戶調整大小

WINDOW_FREERATIO

窗口大小自適應比例

WINDOW_KEEPRATIO

保持圖像的比例

1、具體代碼展示標志效果

1.1 窗口大小可變

cv.namedWindow("show Image",cv.)

或者 cv.namedWindow("show Image",cv.WINDOW_GUI_NORMAL)

或者 cv.namedWindow("show Image",0)

此時的圖片是可以自由拉伸改變大小的

1.2 窗口大小不可變,自動適應圖片大小(默認)

cv.namedWindow("show Image",cv.WINDOW_AUTOSIZE)

或者 cv.namedWindow("show Image",1)

1.3 窗口大小自適應比例

cv.namedWindow("show Image",cv.WINDOW_FREERATIO)

1.4 窗口大小跟隨圖片保持其比例

cv.namedWindow("show Image",cv.WINDOW_KEEPRATIO)

說明:如果在imshow()之前加上namedWindow()方法來顯示一張圖片的話,該窗口顯示的圖片是可交互的。

1、這里使用imshow()和namedWindow()方法時候窗口的標識名稱(傳遞的第一個參數)要一樣。

2、namedWindow()方法要寫在imshow()方法之前才可以。

?API名:cv.namedWindow(winname, flags=None)

參數:winname

窗口名字

flags窗口標志

標志參數

作用

WINDOW_NORMAL

顯示圖像后,允許用戶隨意調整窗口大小

WINDOW_AUTOSIZE

根據圖像大小顯示窗口,不允許用戶調整大小

WINDOW_FREERATIO

窗口大小自適應比例

WINDOW_KEEPRATIO

保持圖像的比例

1、具體代碼展示標志效果

1.1 窗口大小可變

cv.namedWindow("show Image",cv.)

或者 cv.namedWindow("show Image",cv.WINDOW_GUI_NORMAL)

或者 cv.namedWindow("show Image",0)

此時的圖片是可以自由拉伸改變大小的

1.2 窗口大小不可變,自動適應圖片大小(默認)

cv.namedWindow("show Image",cv.WINDOW_AUTOSIZE)

或者 cv.namedWindow("show Image",1)

1.3 窗口大小自適應比例

cv.namedWindow("show Image",cv.WINDOW_FREERATIO)

1.4 窗口大小跟隨圖片保持其比例

cv.namedWindow("show Image",cv.WINDOW_KEEPRATIO)

說明:如果在imshow()之前加上namedWindow()方法來顯示一張圖片的話,該窗口顯示的圖片是可交互的。

1、這里使用imshow()和namedWindow()方法時候窗口的標識名稱(傳遞的第一個參數)要一樣。

2、namedWindow()方法要寫在imshow()方法之前才可以。


三、代碼示例

使用 Matplotlib顯示圖片

import cv2

from matplotlib import pyplot as plt

?

if __name__ == "__main__":

????img = cv2.imread('1.jpg',0)

????plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')

????plt.xticks([]), plt.yticks([]) ?# to hide tick values on X and Y axis

plt.show()

使用 Matplotlib顯示圖片并進行一些操作

import cv2

from matplotlib import pyplot as plt

?

if __name__ == "__main__":

????img = cv2.imread('2.jpg')

????edges = cv2.Canny(img,100,200)

?

????plt.subplot(121),plt.imshow(img,cmap = 'gray')

????plt.title('Original Image'), ?plt.xticks([]), plt.yticks([])

????plt.subplot(122),??plt.imshow(edges,cmap = 'gray')

????plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

????plt.show()

說明:plt.imshow()函數負責對圖像進行處理,并顯示其格式,而plt.show()則是將plt.imshow()處理后的函數顯示出來。



二、圖像處理基礎

1.1、獲取圖像屬性

所謂獲取圖像屬性,實際上就說當我們把一幅圖像讀入內存后,這幅圖像就如同一個三維或二維數組,那既然是個numpy數組,必然可以獲取它的shape、它的size以及它的dtype。乃至于,你可以像操作numpy數組那樣,在圖像上做諸如求平均值、方差之類的各種數學操作。因此,實際上獲取圖像的屬性操作也很簡單,比如下面這個例子就分別展示了如何獲得圖像的shape(指示是三維還是二維圖像,或者說彩色圖還是灰度圖)、size(圖像中像素的總數,依據這個總數以及每個像素的dtype就可以獲得這幅圖像當前總共占據多少內存存儲空間)、dtype(每個像素值的數據類型:float32還是int等等):

img = cv2.imread('test.jpg')

獲取圖像的屬性

img.shape

可以獲取圖像的形狀。他的返回值是:一個包含(行數(高),列數(寬), 通道數)的元組。

img.size

返回圖像的像素數目

img.dtype

返回返回圖像的數據類型

API名:cv2.imwrite('圖像文件地址',圖像變量)

將圖像變量保存到指定位置的指定文件中

先查看原始圖像的shape、size、dtype:(675, 1200, 3) 2430000?uint8

再查看顏色模式為HSV后的圖像的shape、size、dtype:(675, 1200, 3) 2430000?uint8

最后查看變成灰度圖后圖像的shape、size、dtype:(675, 1200) 810000?uint8

從結果來看,當彩色圖變成灰度圖之后,通道數沒有了,意味著圖像的像素總數也會大幅減少。


1.2 圖像像素更改

????????圖像像素的更改行為,往往在機器視覺中是最最簡單的一種行為,其操作起來也如同我們更改一個list或者一個numpy數組中的元素那樣簡單。要知道,任何一幅圖像實際上讀到內存之后就是一個numpy數組,因此,圖像像素的修改就如同我們在修改一個n維數組中的某個元素那樣簡單。所不同的是,修改圖像像素,我們需要指定圖像像素的坐標:

?????????如果是RGB格式的,坐標就分別是R、G、B三個通道的值來共同定位一個像素;如果是HSV或別的什么顏色模式下的圖像,也如同像RGB那樣指定出三維坐標系各個坐標軸上的坐標值即可。

????????如果是一個灰度圖,則如同一個平面坐標系那般簡單,只需要指定橫縱坐標的值即可圈定一個像素。

????????當然,通常情況下,我們只需要給出像素的行和列坐標值即可獲得像素內的值。此時,對于RGB或HSV等三維顏色格式的圖像來說,返回的是圖像的三維坐標的值,比如RGB就是返回R、G、B;HSV的就是返回H、S、V;對于灰度圖來說則是返回的是灰度值。

????????同時,給定像素的行、列坐標值就可以依據像操作numpy二維數組那樣來給指定的像素點修改像素值。

獲取像素值并修改

參數含義:y坐標x:x坐標

bgr:BGR通道,0:B通道,1:G通道,2:R通道

獲取像素值?img[y,x]

獲取(x,y)處的通道值,返回列表


img = cv2.imread('test.jpg')

# 獲取像素值px = img[100, 200]

img[y,x,bgr]?

獲取(x,y)處一個通道值

獲取像素中的B通道顏色值blue = img[100, 200, 0]

修改像素值?img[y,x]=[b,g,r]

將一個顏色賦值給一個像素點

# 修改像素值img[100, 200] = [0, 123, 155]

比如下面這段小代碼就很好地解釋了如何獲取不同顏色格式下的像素值內容:

import numpy as npimport cv2#讀入原始圖片,并將其進行顏色空間轉換為HSV和灰度圖#再分別讀出相同的行、列坐標值下的像素值以加深對像素值更操作的理解
import numpy as npimport cv2#讀入原始圖片,并將其進行顏色空間轉換為HSV和灰度圖#再分別讀出相同的行、列坐標值下的像素值以加深對像素值更操作的理解
img = cv2.imread(r'E:\tmp\maerdaifu.jpg',cv2.IMREAD_UNCHANGED)
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print('以下為不同顏色模式下獲取像素值的輸出結果')
print(img[100,100])
print(hsv[100,100])
print(gray[100,100])img[100,100]=[192, 212, 222]
hsv[100,100]=[198, 218, 228]
gray[100,100]=255print('以下為不同顏色模式下修改像素值的輸出結果')
print(img[100,100])
print(hsv[100,100])
print(gray[100,100])

以下為不同顏色模式下獲取像素值的輸出結果

[217 121 ?55][108 190 217]??

以下為不同顏色模式下修改像素值的輸出結果[192 212 222][198 218 228]

1.3 獲取圖像的感興趣區域(ROI)

????????圖像的感興趣區域(ROI:region of interest),是指在機器視覺、圖像處理中,從被處理的圖像以方框、圓、橢圓、不規則多邊形等方式勾勒出需要處理的區域,稱為感興趣區域。在圖像處理領域,感興趣區域是從圖像中選擇的一個圖像區域,這個區域是你的圖像分析所關注的重點。圈定該區域以便進行進一步處理。使用ROI圈定你想讀的目標,可以減少處理時間,增加精度。感興趣區是圖像的一部分,它通過在圖像上選擇或使用諸如設定閾值(thresholding) 或者從其他文件(如矢量> 轉換獲得等方法生成。感趣區可以是點、線、面不規則的形狀,通常用來作為圖像分類的樣本、掩膜、裁剪區或及其他操作。

????????比如,我想要摳出下面這幅圖中的房子:

圖1 馬爾代夫風景圖

????????那么首先我需要知道圖中的房子大約在哪些像素坐標范圍之內,也即其行坐標范圍和列坐標范圍。這里我們需要事先弄清楚感興趣區域在圖像中的坐標范圍:即行列坐標的坐標值范圍。

????????確定坐標范圍后,我們利用切片操作,像在Numpy數組中獲取一定范圍內的數據那樣,即可獲得我們感興趣的區域內的目標對象——房子。整個獲取ROI的代碼如下所示:

import cv2
#讀入原始圖片
img = cv2.imread(r'E:\tmp\maerdaifu.jpg',cv2.IMREAD_UNCHANGED)
#扣除我們感興趣的房子區域并予以單獨顯示
house = img[126:353,316:908]
cv2.imshow('HouseTest1', house)
#我們再把摳出來的房子放至原圖像的其他區域,再顯示操作過后的原始圖像img[326:553,500:1092]=house
cv2.imshow('HouseTest2', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

其運行結果如下:

圖2 摳出的ROI圖像

圖3 將ROI圖像重新放置回原始圖中的運行效果圖

????????從以上兩幅圖來看,我們大體上知道了如何來獲取一個ROI圖像。

????????需要注意的是:圖像在內存中的存儲格式是一個numpy數組,因此,當你給定行列坐標值范圍時,一定要把列坐標范圍放置在切片操作的第一個參數值上,行坐標值范圍為切片操作的第二個參數。這是大家在實際利用numpy數組開展切片操作或其他需要用到行列坐標參與運算時最最容易犯的錯誤之一。

1.4 圖像通道的拆分、合并操作

????????當我們需要單獨對圖像的通道進行操作,比如R、G、B三個通道都有不同的操作時,我們就需要用到通道的拆分。當拆分后的通道被處理結束之后,可能需要將其復原時,又需要用到通道的合并操作。由于我們再三強調過讀入一幅圖像到內存后,其實質就是讀入一個numpy數組,因此,在numpy的基礎知識講解中,如何拆分和合并不同的維度,這里就可以用同樣的API來操作,也即利用split()來拆分通道,利用merge()來合并通道,

拆分通道1:?b,g,r = cv2.split(m,mv)

m:? 圖像imgmv:? 默認為None

# 分離顏色通道

b, g, r = cv2.split(img)

cv2.imshow('Blue', b)

cv2.imshow('Green', g)

cv2.imshow('Red', r)

拆分通道2:

b=img[:,:,bgr]

# 其他方法

b1 = img[:, :, 0] # 僅取B通道

cv2.imshow('Blue-1', b1)

b2 = cv2.imread('test.jpg')

b2[:, :, 1:3] = 0 # 將0賦值給G、R通道

cv2.imshow('Blue-2', b2)

合并通道?img = cv2.merge([X,Y,Z])

mergeImg?= cv2.merge([b, g, r])

cv2.imshow('merge', mergeImg?)

mergeImg2?= cv2.merge([h, s, v])

cv2.imshow('merge', mergeImg2?)

import cv2#讀入原始圖片
img = cv2.imread(r'E:\tmp\maerdaifu.jpg',cv2.IMREAD_UNCHANGED)
r,g,b = cv2.split(img) #請大家注意一下merge函數的參數給定形式,如果不以list  或tuple方式來給定的話,必然會出錯
img = cv2.merge([r,g,b])
cv2.imshow('Test', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

其運行結果如下:

圖4 通道拆分合并效果圖

可以看出,通道經拆分再合并后得到的圖像與原始圖像并無二致。

#通道的分離與合并以及某個通道值的修改
import cv2 as cv
src=cv.imread('E:\imageload\example.png')
cv.namedWindow('first_image', cv.WINDOW_AUTOSIZE)
cv.imshow('first_image', src)
#三通道分離形成單通道圖片
b, g, r =cv.split(src)
cv.imshow("second_blue", b)
cv.imshow("second_green", g)
cv.imshow("second_red", r)
# 其中cv.imshow("second_red", r)可表示為r = cv2.split(src)[2]
#三個單通道合成一個三通道圖片
src = cv.merge([b, g, r])
cv.imshow('changed_image', src)#修改多通道里的某個通道的值
src[:, :, 2] = 0
cv.imshow('modify_image', src)cv.waitKey(0)
cv.destroyAllWindows()

5、添加邊界(padding)/為圖像擴邊

cv2.copyMakeBorder(src,top, bottom, left, right,borderType,value)

src: 輸入圖像

? top, bottom, left, right 對應邊界的像素數目。

value: 邊界顏色,如果borderType為cv2.BORDER_CONSTANT時,傳入的邊界顏色值,如[0,255,0]

borderType: 要添加那種類型的邊界,類型如下

–cv2.BORDER_CONSTANT 添加有顏色的常數值邊界,還需要下一個參數(value)。

– cv2.BORDER_REFLECT邊界元素的鏡像。比如: fedcba|abcdefgh|hgfedcb

– cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 跟上面一樣,但稍作改動。例如: gfedcb|abcdefgh|gfedcba

– cv2.BORDER_REPLICATE重復最后一個元素。例如: aaaaaa| abcdefgh|hhhhhhh

– cv2.BORDER_WRAP 不知道怎么說了, 就像這樣: cdefgh| abcdefgh|abcdefg

import cv2
import numpy as np
from matplotlib import pyplot as pltBLUE = [255, 0, 0]img = cv2.imread('test.jpg')
replicate = cv2.copyMakeBorder(img, 30, 30, 30, 30, cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, 30, 30, 30, 30, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, 30, 30, 30, 30, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, 30, 30, 30, 30, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, 30, 30, 30, 30, cv2.BORDER_CONSTANT, value=BLUE)plt.subplot(231),
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB), 'gray'),   plt.title('ORIGINAL')
plt.subplot(232),
plt.imshow(cv2.cvtColor(replicate,cv2.COLOR_BGR2RGB),'gray'),  plt.title('REPLICATE')
plt.subplot(233), 
plt.imshow(cv2.cvtColor(reflect, cv2.COLOR_BGR2RGB), 'gray'),   plt.title('REFLECT')
plt.subplot(234), 
plt.imshow(cv2.cvtColor(reflect101, cv2.COLOR_BGR2RGB), 'gray'),   plt.title('REFLECT_101')
plt.subplot(235), 
plt.imshow(cv2.cvtColor(wrap, cv2.COLOR_BGR2RGB), 'gray'),    plt.title('WRAP')
plt.subplot(236), 
plt.imshow(cv2.cvtColor(constant, cv2.COLOR_BGR2RGB), 'gray'), plt.title('CONSTANT')
plt.show() 
  • 使用示例:
import cv2 as cv
import matplotlib.pyplot as pltimg2 = cv.imread(r"C:\Users\Administrator\Desktop\dog.jpg")
img = cv.cvtColor(img2,cv.COLOR_BGR2RGB)  #matplotlib的圖像為RGB格式
constant = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_CONSTANT,value=[0,255,0]) #綠色
reflect = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_REFLECT)
reflect01 = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_REFLECT_101)
replicate = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_REPLICATE)
wrap = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_WRAP)
titles = ["constant","reflect","reflect01","replicate","wrap"]
images = [constant,reflect,reflect01,replicate,wrap]
for i in range(5):plt.subplot(2,3,i+1),plt.imshow(images[i]),plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20221.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20221.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20221.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[有監督學習]2.詳細圖解正則化

正則化 正則化是防止過擬合的一種方法,與線性回歸等算法配合使用。通過向損失函數增加懲罰項的方式對模型施加制約,有望提高模型的泛化能力。 概述 正則化是防止過擬合的方法,用于機器學習模型的訓練階段。過擬合是模型在驗證數據上產生的誤…

Java文件IO

White graces:個人主頁 🙉專欄推薦:Java入門知識🙉 🙉 內容推薦:JUC常見類🙉 🐹今日詩詞:東風吹柳日初長,雨馀芳草斜陽🐹 ??點贊 ??收藏??關注💬卑微小博主&…

Three.js 研究:4、創建設備底部旋轉的科技感圓環

1、實現效果 2、PNG轉SVG 2.1、原始物料 使用網站工具https://convertio.co/zh/png-svg/進行PNG轉SVG 3、導入SVG至Blender 4、制作旋轉動畫 4.1、給圓環著色 4.2、修改圓環中心位置 4.3、讓圓環旋轉起來 參考一下文章 Three.js 研究:1、如何讓物體動起來 Thre…

LeetCode # 1070. 產品銷售分析 III

1070. 產品銷售分析 III 題目 銷售表 Sales: ------------------ | Column Name | Type | ------------------ | sale_id | int | | product_id | int | | year | int | | quantity | int | | price | int | ------------------ (sale_id, year) 是這張表的主鍵&am…

“論SOA在企業集成架構設計中的應用”必過模板,突擊2024軟考高項論文

考題部分 企業應用集成(Enterprise Application Integration, EAI)是每個企業都必須要面對的實際問題。面向服務的企業應用集成是一種基于面向服務體系結構(Service-OrientedArchitecture,SOA)的新型企業應用集成技術,強調將企業和組織內部的資源和業務功…

VSCode界面Outline只顯示類名和函數名,隱藏變量名

參考鏈接 https://blog.csdn.net/Zjhao666/article/details/120523879https://blog.csdn.net/Williamcsj/article/details/122401996 VSCode中界面左下角的Outline能夠方便快速跳轉到文件的某個類或函數,但默認同時顯示變量,導致找某個函數時很不方便。…

mimkatz獲取windows10明文密碼

目錄 mimkatz獲取windows10明文密碼原理 lsass.exe進程的作用 mimikatz的工作機制 Windows 10的特殊情況 實驗 實驗環境 實驗工具 實驗步驟 首先根據版本選擇相應的mimikatz 使用管理員身份運行cmd 修改注冊表 ?編輯 重啟 重啟電腦后打開mimikatz 在cmd切換到mi…

Seq2Seq模型:詳述其發展歷程、深遠影響與結構深度剖析

Seq2Seq(Sequence-to-Sequence)模型是一種深度學習架構,專為處理從一個輸入序列到一個輸出序列的映射任務設計。這種模型最初應用于機器翻譯任務,但因其靈活性和有效性,現已被廣泛應用于自然語言處理(NLP&a…

醫院該如何應對網絡安全?

在線醫生咨詢受到很多人的關注,互聯網醫療行業的未來發展空間巨大,但隨著醫院信息化建設高速發展 醫院積累了大量的患者基本信息、化驗結果、電子處方、生產數據和運營信息等數據 這些數據涉及公民隱私、醫院運作和發展等多因素,醫療行業辦…

【QEMU中文文檔】1.關于QEMU

本文由 AI 翻譯(ChatGPT-4)完成,并由作者進行人工校對。如有任何問題或建議,歡迎聯系我。聯系方式:jelin-shoutlook.com。 QEMU 是一款通用的開源機器仿真器和虛擬化器。 QEMU 可以通過幾種不同的方式使用。最常見的用…

OrangePi AIpro--新手上路

目錄 一、SSH登錄二、安裝VNC Sevice(經測試Xrdp遠程桌面安裝不上)2.1安裝xface桌面2.2 配置vnc服務2.2.1 設置vnc server6-8位的密碼2.2.2 創建vnc文件夾,寫入xstartup文件2.2.3 給xstartup文件提高權限2.2.4 在安裝產生的vnc文件夾創建xsta…

C# 工廠模式學習

工廠模式(Factory Pattern)是一種創建型設計模式,它提供了一種創建對象的接口,而不是通過具體類來實例化對象。工廠模式可以將對象的創建過程封裝起來,使代碼更具有靈活性和可擴展性。 工廠模式有幾種常見的實現方式&…

Go 如何通過 Kafka 客戶端庫 生產與消費消息

文章目錄 0.前置說明1. confluent-kafka-go2. sarama3. segmentio/kafka-go4. franz-go選擇建議 1.啟動 kafka 集群2.安裝 confluent-kafka-go 庫3.創建生產者特殊文件說明如何查看.log文件內容 4.創建消費者 0.前置說明 Go 語言中有一些流行的 Kafka 客戶端庫。以下是幾個常用…

【Uniapp小程序】自定義導航欄uni-nav-bar滾動漸變色

效果圖 新建activityScrollTop.js作為mixins export default {data() {return {navBgColor: "rgba(0,0,0,0)", // 初始背景顏色為完全透明navTextColor: "rgba(0,0,0,1)", // 初始文字顏色};},onPageScroll(e) {// 設置背景const newAlpha Math.min((e.s…

踩坑:6年后為何不用GraphQL了?

GraphQL 是一項令人難以置信的技術,自從我在 2018 年首次開始將其投入生產以來,它就吸引了很多人的注意力。 在一大堆無類型的 JSON REST API 上構建了許多 React SPA 之后,我發現 GraphQL 是一股清新的空氣。 然而,隨著時間的推…

mybatis用map接收返回對象,不想讓數據類型為tinyint自動轉換為boolean,如何處理

在 MyBatis 中,當使用 Map 來接收查詢結果時,MyBatis 會根據列的數據類型自動選擇合適的 Java 類型來映射這些值。默認情況下,如果數據庫列是 TINYINT(1),MyBatis 可能會錯誤地將其映射為 boolean,因為它經常被誤解為只…

PPP認證兩種:PAP和CHAP,兩次握手和三次握手

CHAP(Challenge-Handshake Authentication Protocol,質詢握手認證協議)的設計理念是增強網絡認證過程的安全性。在CHAP的三次握手過程中,不直接傳送用戶的明文密碼,以此來提高安全性,具體步驟如下&#xff…

開源大模型源代碼

開源大模型的源代碼可以在多個平臺上找到,以下是一些知名的開源大模型及其源代碼的獲取方式: 1. **艾倫人工智能研究所的開放大語言模型(Open Language Model,OLMo)**: - 提供了完整的模型權重、訓練代…

springboot結合mybatis使用多數據源的方式

背景 最近有一個需求,有兩個庫需要做同步數據,一個Doris庫,一個mysql庫,兩邊的表結構一致,這里不能使用navicat等工具提供的數據傳輸之類的功能,只能使用代碼做同步,springboot配置多數據…

如何設置手機的DNS

DNS 服務器 IP 地址 蘋果 華為 小米 OPPO VIVO DNS 服務器 IP 地址 中國大陸部分地區會被運營商屏蔽網絡導致無法訪問,可修改手機DNS解決。 推薦 阿里的DNS (223.5.5.5)或 114 (114.114.114.114和114.114.115.115) 更多公開DNS參考: 蘋果…