读书人

多线程处理图像有关问题求大神指点迷

发布时间: 2013-01-05 15:20:39 作者: rapoo

多线程处理图像问题,求大神指点迷津!!
下面代码是处理图片的代码,大致是通过定位图片中直线坐标,再经过坐标变换求出相对坐标中的涂黑点,然后将涂黑点保存到数据库中,不用线程时,执行该过程一切正常,读取的结果和实际吻合,说明读取正确,因为要处理大量图片,执行时间长,是屏幕锁死会锁死很久。这个应该正常。
现在为了提高处理速度。改为多线程后。线程中
procedure TGetDataThd.Execute;
方法用 synchronize(doreadsp); 去执行发现屏幕依旧锁死,读取结果也是正确的。
procedure TGetDataThd.Execute;
改用 doreadsp; 去执行屏幕不锁死了,但是读取结果不正确。
依然用 synchronize(doreadsp); 去执行。同时开5个线程去运行,屏幕锁死,5顺序顺序执行,并没有达到5个线程并行运行从而提高处理速度的预期效果。
例如有100个图片,每20个图片分一组,分别开5个线程运行,运行时间是20个图片处理时间*5而非预期的运行时间减少为1/5
。查了一些资料和翻了很多遍csdn以前的帖子都找不到答案,求大神指点迷津啊。

下面是主要处理图片的代码,可能一些算法需要优化,现在顾不上了,只求能搞定多线程处理图片的问题。

procedure TGetDataThd.DoReadSp;
const
MCW_EM = DWord($133f);
var
i,j,ret,iztscore,icontentscore,iLineCount:integer;
bTempb,testbmp:Tbitmap;
sCheckInfo,model_cls:string;
strBarcode : String;
DecodePara : PTDECODEPARASTRUCT;
BarCodeInfo : PTTOTALBARCODEINFOSTRUCT;
pInfo: pPTBARCODEINFOSTRUCT;
modelid,checkid,cadreid,cadreidlist,zt_pose_count,cadre_pose_count,content_pose_count,use_opinion_flag,zt_pose,content_pose:string;
overall_flag,content_line_direction,card_rowcount,card_colcount:string;
zt_posetmp,content_posetmp,zt_Score,content_score:string;
//原点和斜率定义
iX,iY,iPoseArray,iPose:integer;
AX,AY,BX,BY,CX,CY,AX0,AY0,BX0,BY0,CX0,CY0,DX0,DY0,ox,oy,LPose:integer;
posestates:string;
BlackFound:boolean;
fK:real;
scheckmodel:string;
sSorPath,sDitPath,deptid:string;
bfound:boolean;
adoquery1,ADOQuery2:Tadoquery;
begin
//search the whole image
Set8087CW(MCW_EM);
j:=iStart;
if iList=1 then
begin
CardDistinNewForm.ProgressBar1.Visible:=true;
CardDistinNewForm.ProgressBar1.Progress:=1;
CardDistinNewForm.ProgressBar1.MaxValue:=iEnd-iStart+1;
end;
if iList=2 then
begin
CardDistinNewForm.ProgressBar2.Visible:=true;
CardDistinNewForm.ProgressBar2.Progress:=1;
CardDistinNewForm.ProgressBar2.MaxValue:=iEnd-iStart+1;
end;
if iList=3 then
begin
CardDistinNewForm.ProgressBar3.Visible:=true;
CardDistinNewForm.ProgressBar3.Progress:=1;
CardDistinNewForm.ProgressBar3.MaxValue:=iEnd-iStart+1;
end;
if iList=4 then
begin
CardDistinNewForm.ProgressBar4.Visible:=true;
CardDistinNewForm.ProgressBar4.Progress:=1;
CardDistinNewForm.ProgressBar4.MaxValue:=iEnd-iStart+1;
end;
try
adoquery1:=Tadoquery.Create(nil);
adoquery2:=Tadoquery.Create(nil);
adoquery1.Connection:=DataConnDataModel.ADOConn;
adoquery2.Connection:=DataConnDataModel.ADOConn;
while J<=iEnd do
begin
sSorPath:=copy(trim(CardDistinNewForm.AdvStringGrid1.cells[2,j]),length(trim(CardDistinNewForm.edit1.Text))+1,length(trim(CardDistinNewForm.AdvStringGrid1.cells[2,j])));
sDitPath:=trim(CardDistinNewForm.edit6.Text)+sSorPath;


bTempb:=Tbitmap.Create;
bTempb:=Pic2Bmp(trim(CardDistinNewForm.AdvStringGrid1.cells[2,j]));
testbmp:=bTempb;
sCheckInfo:='0012-010-001';
modelid:=getModelId(sCheckInfo);
checkid:=getCheckId(sCheckInfo);

ADOQuery1.Close;
ADOQuery1.SQL.Text:='select cadre_list_id d1,zt_pose as d2,content_pose as d3'
+' from card_content_pose where model_id='''+trim(sCheckInfo) +''' order by cadre_list_id';
ADOQuery1.Open;
if adoquery1.Eof=false then
scheckmodel:=trim(sCheckInfo) //考核卡信息
else
begin
cadreid:=copy(sCheckInfo,length(sCheckInfo)-2,3) ;
adoquery1.Close;
adoquery1.SQL.Text:='select dpt_id as d1 from objece_set where check_id='''
+checkid+''' and card_id='''+cadreid+'''';
adoquery1.Open;
if adoquery1.Eof=false then
deptid:=trim(adoquery1.fieldbyname('d1').AsString);
adoquery1.Close;
ADOQuery1.SQL.Text:='select cadre_list_id d1,zt_pose as d2,content_pose as d3'
+' from card_content_pose where model_id='''+sCheckInfo+''' order by cadre_list_id';
ADOQuery1.Open;
if adoquery1.Eof=false then
scheckmodel:=sCheckInfo
else
scheckmodel:=copy(sCheckInfo,1,8);

end;
cadreidlist:=getCadreList(sCheckInfo);
ADOQuery1.Close;
ADOQuery1.SQL.Text:='select list_id d1,zt_pose_count as d2,cadre_pose_count as d3,content_pose_count as d4,'
+'use_opinion_flag as d5,overall_flag as d6,content_line_direction as d7,card_rowcount as d8,card_colcount as d9,model_cls as d10'


+' from card_model where list_id='''+modelid+'''';
ADOQuery1.Open;
if ADOQuery1.Eof=false then
begin
zt_pose_count:=trim(ADOQuery1.fieldbyname('d2').AsString);
cadre_pose_count:=trim(ADOQuery1.fieldbyname('d3').AsString);
content_pose_count:=trim(ADOQuery1.fieldbyname('d4').AsString);
use_opinion_flag:=trim(ADOQuery1.fieldbyname('d5').AsString);
overall_flag:=trim(ADOQuery1.fieldbyname('d6').AsString);
content_line_direction:=trim(ADOQuery1.fieldbyname('d7').AsString);
card_rowcount:=trim(ADOQuery1.fieldbyname('d8').AsString);
card_colcount:=trim(ADOQuery1.fieldbyname('d9').AsString);
model_cls:=trim(ADOQuery1.fieldbyname('d10').AsString);
end;
//************开始*****************获得图片原点和X轴斜率


//从左到右
iX:=40;
posestates:='0';
LPose:=0;
iPose:=0;

while iX<testbmp.Width-40 do
begin
iY:=testbmp.Height-40;
BlackFound:=false;
while iY>testbmp.Height-600 do
begin
// memo1.Lines.Add(ColorToString(testbmp.Canvas.Pixels[ix,iy])+'('+inttostr(ix)+','+inttostr(iy)+')');
//CardDistinNewForm.Memo1.Lines.Add(inttostr(ix)+','+inttostr(iY));
if testbmp.Canvas.Pixels[ix,iy]=clBlack then
begin

if posestates='0' then
begin
posestates:='1';
AX:=iX;
AY:=iY;
BX:=iX;
BY:=iY;
end;
if posestates='1' then
begin
CX:=iX;
CY:=iY;
end;
BlackFound:=true;
break;


end;
iY:=iY-1;
end;
if BlackFound=true then
begin
if ABS(CY-BY)<=1 then
begin
BX:=CX;
BY:=CY;
LPose:= LPose+1;
if LPose>15 then
begin
iPose:=iPose+1;
if iPose=1 then
begin
AX0:=round((AX+BX)/2+0.1);
AY0:=round((AY+BY)/2+0.1);
end;
if iPose>1 then
begin
BX0:=round((AX+BX)/2+0.1);
BY0:=round((AY+BY)/2+0.1);
end;
end;
end
else
begin
posestates:='0';
LPose:=0;
end;
end
else
begin
posestates:='0';
LPose:=0;
end;
iX:=iX+1;
end;
ix:=145;
iy:=139;


[解决办法]
每个线程处理一个图片分几个步骤:
1、取图片,本地,无须synchronize同步,费时x秒(与图片文件大小有关,假设x=1)
2、处理,数据空间独立,无须synchronize同步,费时y秒(y=50)
3、保存,与生成的字符串大小有关,共用ado连接则需要synchronize同步,费时z秒(与字符串大小有关,假设z=3)

则只有3是需要排队执行的,1、2应该可以同时进行。不过,如果cpu单核或并行差,1、2的并行也会互等

如果ado是每个线程独立有一个连接,则3也可以并行,这样需要程序先CoInitializeEx一次。。。。搜一下就知道了

读书人网 >.NET

热点推荐