【精選】??通道熱點加持的LW-ResNet:小麥病害智能診斷與防治系統

1.研究背景與意義

小麥是世界上最重要的糧食作物之一,但由于病害的侵襲,小麥產量和質量受到了嚴重的威脅。因此,開發一種高效準確的小麥病害識別分類防治系統對于保障糧食安全和農業可持續發展具有重要意義。

傳統的小麥病害識別分類方法主要依賴于人工觀察和經驗判斷,這種方法存在著識別效率低、準確性不高的問題。而隨著計算機視覺和深度學習技術的快速發展,基于圖像處理和機器學習的小麥病害識別分類方法逐漸成為研究熱點。

近年來,深度學習在圖像識別領域取得了顯著的成果。然而,傳統的深度卷積神經網絡(CNN)在處理小麥病害圖像時面臨著一些挑戰。首先,小麥病害圖像通常具有復雜的紋理和形狀特征,傳統的CNN模型往往難以捕捉到這些細節信息。其次,小麥病害圖像中的病害部分往往只占整個圖像的一小部分,而傳統的CNN模型往往會將整個圖像作為輸入,導致對病害部分的關注不足。

為了解決上述問題,本研究提出了一種基于通道注意力LW-ResNet的小麥病害識別分類防治系統。該系統主要包括兩個關鍵部分:通道注意力機制和LW-ResNet模型。

通道注意力機制是一種自適應的注意力機制,它能夠根據圖像的內容自動調整各個通道的權重,從而使網絡更加關注重要的特征。在小麥病害識別分類任務中,通道注意力機制可以幫助網絡更好地捕捉到病害圖像中的細節信息,提高識別準確性。

LW-ResNet模型是一種改進的殘差網絡模型,它結合了局部窗口和全局窗口的特征信息。在小麥病害識別分類任務中,LW-ResNet模型可以通過局部窗口和全局窗口的特征融合,提高網絡對病害部分的關注度,進一步提高識別準確性。

該研究的意義主要體現在以下幾個方面:

首先,基于通道注意力LW-ResNet的小麥病害識別分類防治系統可以提高小麥病害的識別準確性和分類效果,幫助農民及時采取相應的防治措施,減少病害對小麥產量和質量的影響。

其次,該系統可以提高小麥病害的識別效率,減輕人工觀察和經驗判斷的負擔,提高工作效率和決策準確性。

此外,該研究還可以為其他農作物的病害識別分類提供借鑒和參考,促進農業科技的發展和應用。

綜上所述,基于通道注意力LW-ResNet的小麥病害識別分類防治系統具有重要的研究意義和應用價值,對于保障糧食安全、提高農業生產效益具有重要的推動作用。

2.圖片演示

2.png

3.png

4.png

3.視頻演示

基于全局注意力的改進YOLOv7-AC的水下場景目標檢測系統_嗶哩嗶哩_bilibili

4.LW-ResNet 網絡模型

針對自然場景下蘋果病害的特點以及移動設備存儲空間和計算資源有限的應用需求基于ResNet18構建了改進的殘差網絡模型(LW-ResNet),結構如圖所示。
image.png
該網絡在ResNet18的基礎上,將每個Stage減少至1個殘差模塊,并且在殘差模塊中添加了多種感受野尺寸,降低模型的參數量與計算量并獲取多種局部特征。設計池化層與卷積層串聯的方式實現恒等映射,減少信息損失,加強病斑細節特征的表達。在殘差模塊間引入輕量注意力模塊ECANet,抑制由復雜背景產生的環境噪聲在模型學習過程中的傳遞。

5.核心代碼講解

5.1 model.py

class ECANet(nn.Module):def __init__(self, channels):super(ECANet, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.conv = nn.Conv1d(1, 1, kernel_size=3, padding=1, bias=False)self.sigmoid = nn.Sigmoid()def forward(self, x):y = self.avg_pool(x)y = self.conv(y.squeeze(-1).transpose(-1, -2)).transpose(-1, -2).unsqueeze(-1)y = self.sigmoid(y)return x * y.expand_as(x)class ResidualBlock(nn.Module):def __init__(self, in_channels, out_channels, stride=1):super(ResidualBlock, self).__init__()G = 16  # group countmid_channels = out_channels // 4self.conv1 = nn.Conv2d(in_channels, mid_channels, kernel_size=1, stride=stride, bias=False)self.bn1 = nn.BatchNorm2d(mid_channels)self.gconv1 = nn.Conv2d(mid_channels, mid_channels, kernel_size=1, groups=G, bias=False)self.gconv3 = nn.Conv2d(mid_channels, mid_channels, kernel_size=3, groups=G, padding=1, bias=False)self.gconv5 = nn.Conv2d(mid_channels, mid_channels, kernel_size=5, groups=G, padding=2, bias=False)self.gconv7 = nn.Conv2d(mid_channels, mid_channels, kernel_size=7, groups=G, padding=3, bias=False)self.conv2 = nn.Conv2d(mid_channels*4, out_channels, kernel_size=1, bias=False)self.bn2 = nn.BatchNorm2d(out_channels)self.relu = nn.ReLU(inplace=True)self.downsample = nn.Sequential(nn.MaxPool2d(3, stride=2, padding=1),nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)) if stride != 1 or in_channels != out_channels else Nonedef forward(self, x):identity = xout = self.conv1(x)out = self.bn1(out)out = self.relu(out)g1 = self.gconv1(out)g3 = self.gconv3(out)g5 = self.gconv5(out)g7 = self.gconv7(out)out = torch.cat([g1, g3, g5, g7], dim=1)out = self.conv2(out)out = self.bn2(out)if self.downsample:identity = self.downsample(identity)out += identityout = self.relu(out)return outclass LWResNet(nn.Module):def __init__(self, num_classes=2):  # Assuming Binary Classification (Disease/Not Disease)super(LWResNet, self).__init__()self.conv = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1, bias=False)self.bn = nn.BatchNorm2d(16)self.relu = nn.ReLU(inplace=True)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)self.stage1 = self._make_layer(16, 16, 1)self.stage2 = self._make_layer(16, 32, 2)self.stage3 = self._make_layer(32, 64, 2)self.stage4 = self._make_layer(64, 128, 2)self.ecanet1 = ECANet(16)self.ecanet2 = ECANet(32)self.ecanet3 = ECANet(64)self.ecanet4 = ECANet(128)self.avgpool = nn.AdaptiveAvgPool2d((1, 1))self.fc = nn.Linear(128, num_classes)self.softmax = nn.Softmax(dim=1)def _make_layer(self, in_channels, out_channels, stride):return ResidualBlock(in_channels, out_channels, stride)def forward(self, x):x = self.conv(x)x = self.bn(x)x = self.relu(x)x = self.maxpool(x)x = self.stage1(x)x = self.ecanet1(x)x = self.stage2(x)x = self.ecanet2(x)x = self.stage3(x)x = self.ecanet3(x)......
  1. ECANet類:

    • 初始化函數中,定義了avg_pool、conv和sigmoid層。
    • forward函數中,首先對輸入進行平均池化操作,然后將結果經過一系列卷積操作,并使用sigmoid函數進行激活。最后將輸入與激活后的結果相乘并返回。
  2. ResidualBlock類:

    • 初始化函數中,定義了conv1、bn1、gconv1、gconv3、gconv5、gconv7、conv2、bn2、relu和downsample層。
    • forward函數中,首先將輸入保存為identity,然后經過一系列卷積和激活操作,其中gconv1、gconv3、gconv5和gconv7是分組卷積操作。接著將這些操作的結果進行拼接,并經過一次卷積操作。如果downsample不為None,則對identity進行下采樣操作。最后將identity與輸出相加,并經過激活函數后返回。
  3. LWResNet類:

    • 初始化函數中,定義了conv、bn、relu、maxpool、stage1、stage2、stage3、stage4、ecanet1、ecanet2、ecanet3、ecanet4、avgpool、fc和softmax層。
    • _make_layer函數用于生成ResidualBlock層。
    • forward函數中,首先經過一次卷積、批歸一化和激活操作,然后進行最大池化。接著經過stage1、ecanet1、stage2、ecanet2、stage3、ecanet3、stage4和ecanet4的一系列操作。最后進行自適應平均池化、展平、全連接和softmax操作,并返回結果。

以上是對給定代碼的逐文件分析,核心部分是ECANet、ResidualBlock和LWResNet類的定義和實現。

該程序文件名為model.py,主要包含了三個類:ECANet、ResidualBlock和LWResNet。

ECANet類是一個自定義的模塊,包含了一個自適應平均池化層、一個一維卷積層和一個Sigmoid激活函數。該類的forward方法實現了特征圖的通道注意力機制。

ResidualBlock類是一個殘差塊,包含了多個卷積層和批歸一化層。該類的forward方法實現了殘差連接和特征圖的分組卷積。

LWResNet類是一個輕量級的ResNet模型,包含了多個卷積層、批歸一化層、殘差塊和ECANet模塊。該類的forward方法實現了模型的前向傳播過程,包括卷積、池化、殘差塊、通道注意力和全連接層等操作。

該程序文件主要實現了一個輕量級的ResNet模型,并使用了通道注意力機制來提升模型的性能。

5.2 train.py

class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)self.bn1 = nn.BatchNorm2d(64)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)self.layer1 = nn.Sequential(RestNetBasicBlock(64, 64, 1),RestNetBasicBlock(64, 64, 1))self.ca = ChannelAttention(64)self.sa = SpatialAttention()self.layer2 = nn.Sequential(RestNetDownBlock(64, 128, [2, 1]),RestNetBasicBlock(128, 128, 1))self.layer3 = nn.Sequential(RestNetDownBlock(128, 256, [2, 1]),RestNetBasicBlock(256, 256, 1))self.layer4 = nn.Sequential(RestNetDownBlock(256, 512, [2, 1]),RestNetBasicBlock(512, 512, 1))self.spp = SPP()self.conv2 = nn.Conv2d(2048, 512, kernel_size=1)self.avgpool = nn.AdaptiveAvgPool2d(output_size=(1, 1))self.fc = nn.Linear(512, 6)def forward(self, x):out = self.conv1(x)out = self.layer1(out)out = self.ca(out) * outout = self.sa(out) * outout = self.layer2(out)out = self.layer3(out)out = self.layer4(out)out = self.spp(out)out = self.conv2(out)out = self.avgpool(out)out = out.reshape(x.shape[0], -1)out = self.fc(out)return out......

這個程序文件名為train.py,主要功能是訓練一個卷積神經網絡模型來對圖像進行分類。程序的主要步驟如下:

  1. 導入所需的庫和模塊,包括numpy、pandas、torch、sklearn、matplotlib、torchvision等。
  2. 定義數據集的路徑和類別,包括訓練集和測試集的路徑。
  3. 將原始圖像按照類別分別復制到訓練集和測試集的文件夾中。
  4. 進行數據預處理,包括圖像的縮放、裁剪、翻轉、旋轉、顏色調整等操作,并進行歸一化處理。
  5. 創建訓練集和測試集的數據加載器,用于批量加載數據。
  6. 定義卷積神經網絡模型,包括基本的卷積塊、下采樣塊、SPP模塊、通道注意力模塊和空間注意力模塊等。
  7. 將模型移動到GPU上(如果可用)。
  8. 定義優化器、損失函數和學習率衰減策略。
  9. 進行模型訓練,包括多個epoch的循環,每個epoch中進行前向傳播、計算損失、反向傳播和參數更新。
  10. 保存訓練好的模型。
  11. 繪制訓練過程中的損失和準確率曲線。

總體來說,這個程序文件實現了一個卷積神經網絡模型的訓練過程,用于對圖像進行分類。

5.3 ui.py
class RestNetBasicBlock(nn.Module):def __init__(self, in_channels, out_channels, stride):super(RestNetBasicBlock, self).__init__()self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1)self.bn1 = nn.BatchNorm2d(out_channels)self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride, padding=1)self.bn2 = nn.BatchNorm2d(out_channels)def forward(self, x):output = self.conv1(x)output = F.relu(self.bn1(output))output = self.conv2(output)output = self.bn2(output)return F.relu(x + output)class RestNetDownBlock(nn.Module):def __init__(self, in_channels, out_channels, stride):super(RestNetDownBlock, self).__init__()self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride[0], padding=1)self.bn1 = nn.BatchNorm2d(out_channels)self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride[1], padding=1)self.bn2 = nn.BatchNorm2d(out_channels)self.extra = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride[0], padding=0),nn.BatchNorm2d(out_channels))def forward(self, x):extra_x = self.extra(x)output = self.conv1(x)out = F.relu(self.bn1(output))out = self.conv2(out)out = self.bn2(out)return F.relu(extra_x + out)class SPP(nn.Module):def __init__(self):super(SPP, self).__init__()self.pool1 = nn.MaxPool2d(kernel_size=5,stride=1,padding=5 // 2)self.pool2 = nn.MaxPool2d(kernel_size=7, stride=1, padding=7 // 2)self.pool3 = nn.MaxPool2d(kernel_size=13, stride=1, padding=13 // 2)def forward(self,x):x1 = self.pool1(x)x2 = self.pool2(x)x3 = self.pool3(x)return torch.cat([x,x1,x2,x3],dim=1)class ChannelAttention(nn.Module):def __init__(self, in_planes, ratio=16):super(ChannelAttention, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.max_pool = nn.AdaptiveMaxPool2d(1)self.fc1   = nn.Conv2d(in_planes, in_planes // 16, 1, bias=False)self.relu1 = nn.ReLU()self.fc2   = nn.Conv2d(in_planes // 16, in_planes, 1, bias=False)self.sigmoid = nn.Sigmoid()def forward(self, x):avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x))))max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x))))out = avg_out + max_outreturn self.sigmoid(out)class SpatialAttention(nn.Module):def __init__(self, kernel_size=7):super(SpatialAttention, self).__init__()assert kernel_size in (3, 7), 'kernel size must be 3 or 7'padding = 3 if kernel_size == 7 else 1self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)self.sigmoid = nn.Sigmoid()def forward(self, x):avg_out = torch.mean(x, dim=1, keepdim=True)max_out, _ = torch.max(x, dim=1, keepdim=True)x = torch.cat([avg_out, max_out], dim=1)x = self.conv1(x)return self.sigmoid(x)......

ui.py是一個用于圖像分類的程序文件。它使用了PyTorch庫來構建一個卷積神經網絡模型,并使用訓練好的模型權重進行圖像分類。程序文件中還包含了一些輔助函數和類,用于數據預處理、圖像顯示和結果輸出等功能。程序通過讀取輸入的圖像文件路徑,將圖像進行預處理后輸入到模型中進行分類,并將分類結果輸出到界面上。

6.系統整體結構

該工程是一個圖像分類的項目,主要包含三個程序文件:model.py、train.py和ui.py。

model.py文件定義了卷積神經網絡模型的結構,包括ECANet、ResidualBlock和LWResNet三個類。ECANet類實現了通道注意力機制,ResidualBlock類實現了殘差連接,LWResNet類是一個輕量級的ResNet模型。

train.py文件用于訓練模型,包括數據預處理、模型構建、模型訓練和保存等功能。它使用了訓練集和測試集的圖像數據進行訓練,并保存訓練好的模型權重。

ui.py文件是一個圖像分類的界面程序,它使用了訓練好的模型權重進行圖像分類。它通過讀取輸入的圖像文件路徑,將圖像進行預處理后輸入到模型中進行分類,并將分類結果輸出到界面上。

下面是每個文件的功能整理:

文件名功能
model.py定義卷積神經網絡模型的結構,包括ECANet、ResidualBlock和LWResNet三個類
train.py進行模型的訓練,包括數據預處理、模型構建、模型訓練和保存等功能
ui.py圖像分類的界面程序,使用訓練好的模型權重進行圖像分類,包括圖像預處理、模型加載和分類結果輸出等功能

7.多尺度特征提取層

小麥病害識別的難點之一是病斑大小不同,尤其是識別小病斑。由于病斑細節特征的豐富性與其所占像素數成正比[6],微小病斑特征不易提取,從而導致模型整體識別精度的下降。對于ResNet18來說,殘差模塊中只有尺寸為3x3的卷積層,單一尺度的卷積核感受野是固定的,提取到的特征有限,無法滿足識別不同尺寸病斑特別是微小病斑所需的特征信息,還需聯合多個尺度的特征進行鑒別。
然而使用傳統的卷積核獲取多尺度特征的同時也導致了網絡的參數需求大大增加增加了模型訓練與部署的難度。所以AAAI提出的模型選擇參數量與復雜度較低的群卷積構建多尺度特征提取層。將ResNet18的殘差模塊中的第二層卷積替換為4種不同尺度(1×1、3×3、5×5、7×7)的群卷積,實現不同尺度特征的提取[5]。
群卷積操作如圖所示,群卷積將尺寸為HxWxM的特征圖分為G組,每組的輸入通道數為MIG,每組的輸出通道數為NG,卷積核總數為N。
image.png
以LW-ResNet的Stagel中的殘差模塊為例,多尺度特征提取層中每個卷積(1×1,3×3,5×5,7x7)的輸入通道為16,輸出通道為16,特征圖輸入和輸出的尺寸為56×56。
傳統卷積構造的多尺度特征提取層的參數量為12×16×16+32×16×16+52×16×16+72×16×16=21504。
組數為16 ( G=16 )的群卷積構建的多尺度特征提取層的參數數量為12×16×16×1/16+32×16×16×1/16+52×16×16×1/16+7×16×16×1/16=1344,與傳統卷積相比參數數量減少了93.75%。
image.png

同理,由公式可以計算出,傳統卷積構造的多尺度特征提取層的FLOPs為6.74E+07,而群卷積構造的多尺度特征提取層的FLOPs為4.21E+06。

8.輕量高效的通道注意力模塊

由于AAAI提供的數據集使用的圖像為田間環境下的小麥葉部病害圖像,背景復雜,存在諸多環境干擾因素。干擾因素產生的噪聲會在模型學習過程中傳遞,隨著網絡的加深,噪聲信息在特征圖的權重也不斷增加[6],最終對模型的學習效果產生負面影響。通道注意力機制削弱代表背景特征的通道并減少它們的權重[8],從而降低噪聲等干擾因素對模型識別任務的負面影響。
而大多數通道注意力模塊不能同時考慮低復雜性和高性能[9]。例如,經典的SENet模塊t0I使用兩個全連接層在通道之間交換信息和降低特征維數。全連接層的使用使SENet模塊不具備輕量的特點,降維操作使得通道與其預測值沒有直接關系,這對 SENet的整體性能有所影響。
ECANet利用一維卷積結合相鄰通道獲得加權的病斑特征,彌補特征降維帶來的缺陷,實現局部交互,更好地增強病斑區域的特征。此外,ECANet的參數量和復雜度較低,不會過多增加網絡模型的存儲開銷和計算開銷。ECANet適合引入到輕量級網絡結構中以提高模型在復雜環境下關注有效特征的能力,并保持模型的輕量和快速的特性。因此,本章將低復雜度、高效率的ECANet放置在每個殘差模塊后,通過對殘差模塊產生的通道特征重新校準,提高模型的表達能力,最終達到提高模型識別性能的目標。
ECANet結構如圖所示,其中W為特征圖的寬度,H為特征圖的高度,C為通道數量,U代表原始,GAP代表全局平均池化操作,K既代表一維卷積的卷積核大小,也代表局部跨通道交流的范圍,ü為加權后特征。
image.png

9.系統整合

下圖[完整源碼&環境部署視頻教程&自定義UI界面
1.png

參考博客《基于通道注意力LW-ResNet的小麥病害識別分類防治系統》

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

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

相關文章

Feign

目錄 RestTemplate方式調用存在的問題: 定義和使用Feign客戶端 自定義Feign的配置 性能優化 Feign的最佳實踐 Feign的使用步驟: 1、引入依賴 2、添加EnableFeignClients注解 3、編寫FeignClient接口 4、使用FeignClient中定義的方法代替RestTemplate Feign的…

什么是遷移學習

1 遷移學習概述 遷移學習(Transfer Learning)是機器學習中的一種方法,它允許模型將從一個任務中學到的知識應用到另一個相關的任務中。這種方法在數據稀缺的情況下尤為有用,因為它減少了對大量標記數據的需求。遷移學習已成為深度…

Node使用Nvm安裝雙版本切換(node兩個版本同時用怎么辦?不同的項目Node版本要求不一樣怎么辦?)

先把node.js卸載 開始—>添加刪除程序—>node npm -v node -v //檢查是否還存在,卸載成功就行了NVM下載 github下載 百度網盤下載 打開安裝包以管理員身份安裝,要是記得這個路徑并且必須全是英文 使用nvm安裝兩個使用的node版本 cmd以管理員…

計算機組成原理2

1.浮點數 2.IEEE 754 3.存儲器的性能指標 4.存儲器的層次化結構 主存類似手機運行內存8g ,輔存類似手機內存128g.... 輔存必須先通過主存才能被cpu接收,就例如微信打開那個月亮小人界面兩三秒就是主存在讀取輔存的程序然后被cpu接收運行。 5.主存儲…

Greenplum的數據庫年齡檢查處理

概述 Greenplum是基于Postgresql數據庫的分布式數據庫,而PG數據庫在事務及多版本并發控制的實現方式上很特別,采用的是遞增事務id的方法,事務id大的事務,認為比較新,反之事務id小,認為比較舊。 事務id的上…

經典的回溯算法題leetcode組合問題整理及思路代碼詳解

目錄 組合問題 leetcode77題.組合 leetcode216題.組合總和III leetcode40題.組合總和II leetcode39題.組合總和 倘若各位不太清楚回溯算法可以去看我上一篇文章。 回溯算法詳解-CSDN博客 組合問題 一般組合和排列類的問題我們都會轉化成一個樹形問題,更便于…

26. 刪除有序數組中的重復項(remove-duplicates-from-sorted-array)

26. 刪除有序數組中的重復項(remove-duplicates-from-sorted-array) 給你一個 非嚴格遞增排列 的數組 nums ,請你** 原地** 刪除重復出現的元素,使每個元素 只出現一次 ,返回刪除后數組的新長度。元素的 相對順序 應該保持 一致 。然后返回 …

批量創建表空間數據文件(DM8:達夢數據庫)

DM8:達夢數據庫 - - 批量創建表空間數據文件 環境介紹1 批量創建表空間SQL2 達夢數據庫學習使用列表 環境介紹 在某些場景(分區表子表)需要批量創建表空間,給不同的表使用,以下代碼是批量創建表空間的SQL語句; 1 批量創建表空間SQL --創建 24個數據表空間,每個表空間有3個數…

強化學習小筆記 —— 如何選擇合適的更新步長

在強化學習中,動作價值函數的更新可以使用增量法,如下所示: Q k 1 k ∑ i 1 k r i 1 k ( r k ∑ i 1 k ? 1 r i ) 1 k ( r k ( k ? 1 ) Q k ? 1 ) 1 k ( r k k Q k ? 1 ? Q k ? 1 ) Q k ? 1 1 k [ r k ? Q k ? 1 ] \beg…

Linux寶塔面板搭建Discuz論壇, 并內網穿透實現公網訪問

Linux寶塔面板搭建Discuz論壇, 并內網穿透實現公網訪問 文章目錄 Linux寶塔面板搭建Discuz論壇, 并內網穿透實現公網訪問前言1.安裝基礎環境2.一鍵部署Discuz3.安裝cpolar工具4.配置域名訪問Discuz5.固定域名公網地址6.配置Discuz論壇 📷 江池…

低代碼平臺推薦:五大低代碼廠商誰的模式更“合適”

隨著數字化時代的到來,低代碼開發平臺作為提高數字生產力的工具正受到越來越多企業的關注,市面上的低代碼產品和廠商更是“亂花漸欲迷人眼”。 各家產品不僅功能各有不同,甚至商機都有區別的情況,如何做好產品選型已然成了采購企…

C語言——指針(一)

📝前言 這篇文章主要帶大家初步認識一下指針,供大家理解參考。 主要歸納與講解: 1,指針與指針變量 2,指針的基本使用(如何定義,初始化,引用) 🎬個人簡介&…

計算方法 期末總結

思維導圖 緒論 算法的性質: 有窮性、確切性、有輸入輸出、可行性 算法的描述方法: 自然語言、偽代碼、流程圖、N-S流程圖 算法設計思想: 化大為小的縮減技術:二分法化難為易的校正技術:開方法化粗為精的松弛技術&a…

無需公網IP,使用內網穿透實現公網訪問本地OpenWRT管理界面

文章目錄 1.openWRT安裝cpolar2.配置遠程訪問地址3.固定公網地址 簡單幾步實現在公網環境下遠程訪問openWRT web 管理界面,使用cpolar內網穿透創建安全隧道映射openWRT web 界面面板443端口,無需公網IP,無需設置路由器。 1.openWRT安裝cpola…

SpringBoot使用ObjectMapper之Long和BigDemical類型的屬性字符串處理,防止前端丟失數值精度

SpringBoot使用ObjectMapper之Long和BigDemical類型的屬性字符串處理,防止前端丟失數值精度! 方式一:注解 使用注解 JsonFormat(shape JsonFormat.Shape.STRING),如下: import com.fasterxml.jackson.annotation.JsonFormat; …

在arm 64 環境下使用halcon算法

背景: halcon,機器視覺領域神一樣得存在,在windows上,應用得特別多, 但是arm環境下使用得很少。那如何在arm下使用halcon呢。按照官方說明,arm下只提供了運行時環境,并且需要使用價值一萬多人民…

設計高手的秘密武器:5款讓平面作品更出彩的軟件

平面設計是一種迷人而多樣化的藝術形式,它結合了顏色、形狀、排版和創造力,通過圖像和文本傳達信息。市場上有各種各樣的平面設計軟件,選擇合適的設計軟件是成為優秀設計師的重要一步。為了降低軟件成本,大多數設計師會優先使用免…

編譯原理之LL(1)語法分析實驗(附完整C/C++代碼與測試)

一、實驗內容與要求 先從鍵盤讀入要分析的文法,由程序自動構造FIRST、FOLLOW 集以及SELECT集合,判斷是否為LL (1)文法。 分析文法為G[E]: (0)E→ TE’ (1)E’→ TE’ (2&#xff…

軟件開發王者搭配:80%低代碼+20%高代碼

數字化領域從來不缺新概念,前兩年市場大談云原生、技術中臺、業務中臺等概念,企業更多聚焦在業務與IT架構的升級。而這兩年,隨著低代碼、生成式AI的盛行,大家則開始挖掘數字化應用的低成本建設模式。 在過去,開發一套系…

Linux 是否被過譽了?

Linux 是否被過譽了? 有些人眼里,電腦這種東西就應該是華麗麗的桌面,手握鼠標戳戳按鈕,鍵盤只為偶爾打打字,仿佛windows式的桌面形式才是理所應當,GUI才是理所應當,x86才是理所應當&#xff0c…