首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

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

2013-01-05 
多线程处理图像问题,求大神指点迷津!!下面代码是处理图片的代码,大致是通过定位图片中直线坐标,再经过坐标

多线程处理图像问题,求大神指点迷津!!
下面代码是处理图片的代码,大致是通过定位图片中直线坐标,再经过坐标变换求出相对坐标中的涂黑点,然后将涂黑点保存到数据库中,不用线程时,执行该过程一切正常,读取的结果和实际吻合,说明读取正确,因为要处理大量图片,执行时间长,是屏幕锁死会锁死很久。这个应该正常。
现在为了提高处理速度。改为多线程后。线程中
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一次。。。。搜一下就知道了

热点排行